commit 3c39ce6d18dd80c868024c3820886f583f04bcf5
Author: AaronXu <718827633@qq.com>
Date: Thu Nov 13 14:27:03 2025 +0800
init
diff --git a/01.Linux基础/01.初识Linux.md b/01.Linux基础/01.初识Linux.md
new file mode 100644
index 0000000..c1402a5
--- /dev/null
+++ b/01.Linux基础/01.初识Linux.md
@@ -0,0 +1,80 @@
+# 1. 操作系统简介
+
+世上本没有路,走的人多了,便变成了路。——鲁迅
+
+这句话真的是鲁迅说的,出自鲁迅的《故乡》,我们可以理解为一个东西用的人多了,自然而然就会把这个东西的使用方式打磨完善了,人类自动获得了智慧开始就掌握了工具的使用方法。众所周知做不同的事情就需要有不同的方法,走不同的路,也就有了不同的工具。
+
+一台机器往往有不同的零件组成,一台电脑也是由很多不同的硬件组成,这么多的硬件设备,就需要有一个系统去代替我们管理好,这个就是操作系统。
+
+操作系统需要完成的任务很简单,就是去学习每个硬件的不同使用方法,专业的术语叫“安装驱动程序”,当操作系统学会了每个硬件的使用方法之后,就会以某种人类可以操作的方式来被人类使用,有的操作系统是图形化界面的,我们可以鼠标点击来操作,有的是命令行的,我们需要输入命令来操作,不管是哪种方式,最终都是让计算机硬件来为我们而工作。
+
+
+
+# 2. Linux操作系统
+
+不同的人对计算机有不同的操作习惯,不同的使用场景对操作系统有不同的挑战,所以当前就出现了多种多样的操作系统
+
+- Windows
+ - 收费闭源操作系统,主要用于日常办公、游戏、娱乐多一些
+- Linux
+ - 免费的,开源的,主要用于服务器领域,性能稳定,安全
+- Unix
+ - 用于封闭的硬件环境,企业的应用依赖于定制化开发
+
+# 3. Linux图谱
+
+Linux发展到今天出现了大量不同的分支。不同的分支都有不同的发展方向,可以扫描下面二维码,查看Linux发展分支图,或者点开[此链接](https://user-images.githubusercontent.com/19638095/97118180-e25f3680-1708-11eb-8bef-1ebe025e1374.png)。
+
+
+
+# 4. Linux名词
+
+- Linux系统内核指的是一个由Linus Torvalds负责维护,提供硬件抽象层、硬盘及文件系统控制及多任务功能的系统核心程序。
+- Linux发行套件系统是我们常说的Linux操作系统,也即是由Linux内核与各种常用软件的集合产品
+
+# 5. RedHat认证
+
+redhat是目前全球最大的Linux商业公司,redhat为Linux技术工程师提供了一个考试认证,通过这个考试认证的工程师,可以获得redhat公司颁发的证书。
+
+在行业内,redhat的技术证书还是占有很高的含金量的,证书的认证难度依次如下。
+
+
+
+## 5.1 RHCSA
+
+- 管理文件、目录、文档以及命令行环境;
+- 使用分区、LVM逻辑卷管理本地存储;
+- 安装、更新、维护、配置系统与核心服务;
+- 熟练创建、修改、删除用户与用户组,并使用LDAP进行集中目录身份认证;
+- 熟练配置防火墙以及SELinux来保障系统安全。
+
+## 5.2 RHCE
+
+- 熟练配置防火墙规则链与SElinux安全上下文;
+- 配置iSCSI(互联网小型计算机系统接口)服务;
+- 编写Shell脚本来批量创建用户、自动完成系统的维护任务;
+- 配置HTTP/HTTPS网络服务;
+- 配置FTP服务;
+- 配置NFS服务;
+- 配置SMB服务;
+- 配置SMTP服务;
+- 配置SSH服务;
+- 配置NTP服务。
+- 自动化运维工具ansible
+
+## 5.3 RHCA
+
+欲取得红帽RHCA认证,您必须通过以下任意5门认证考试。
+
+| 考试代码 | 认证名称 |
+| :------- | :--------------------------------- |
+| EX210 | 红帽OpenStack 认证系统管理员考试 |
+| EX220 | 红帽混合云管理专业技能证书考试 |
+| EX236 | 红帽混合云存储专业技能证书考试 |
+| EX248 | 红帽认证 JBoss管理员考试 |
+| EX280 | 红帽平台即服务专业技能证书考试 |
+| EX318 | 红帽认证虚拟化管理员考试 |
+| EX401 | 红帽部署和系统管理专业技能证书考试 |
+| EX413 | 红帽服务器固化专业技能证书考试 |
+| EX436 | 红帽集群和存储管理专业技能证书考试 |
+| EX442 | 红帽性能调优专业技能证书考试 |
\ No newline at end of file
diff --git a/01.Linux基础/01.初识Linux/Linux发展分支图.png b/01.Linux基础/01.初识Linux/Linux发展分支图.png
new file mode 100644
index 0000000..7684eb6
Binary files /dev/null and b/01.Linux基础/01.初识Linux/Linux发展分支图.png differ
diff --git a/01.Linux基础/01.初识Linux/RedHat认证.png b/01.Linux基础/01.初识Linux/RedHat认证.png
new file mode 100644
index 0000000..eb274af
Binary files /dev/null and b/01.Linux基础/01.初识Linux/RedHat认证.png differ
diff --git a/01.Linux基础/01.初识Linux/操作系统简介.png b/01.Linux基础/01.初识Linux/操作系统简介.png
new file mode 100644
index 0000000..70cc516
Binary files /dev/null and b/01.Linux基础/01.初识Linux/操作系统简介.png differ
diff --git a/01.Linux基础/02.Linux系统安装.md b/01.Linux基础/02.Linux系统安装.md
new file mode 100644
index 0000000..231252d
--- /dev/null
+++ b/01.Linux基础/02.Linux系统安装.md
@@ -0,0 +1,189 @@
+RockyLinux系统在企业中一般是安装在服务器上的,但是我们学习的时候买台服务器并不方便,所以我们可以将其安装在虚拟机中(实际上很多企业也这么做)
+
+# 1. VMware安装
+
+- 下面是安装过程,从双击安装包开始
+
+
+
+
+
+
+
+
+
+
+
+
+
+- 此处的序列号是:`JU090-6039P-08409-8J0QH-2YR7F`
+
+
+
+
+
+# 2. 创建Linux虚拟机
+
+- 创建步骤如下图
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 3. 安装Linux系统
+
+- 点击开启此虚拟机
+
+
+
+- 鼠标点击进入这个黑框中,通过方向键选择安装选项,回车确认,我们选择第一个:Install Rocky Linux 9.4
+
+
+
+- 依次按照图片所示,完成以下设置
+
+
+
+- 设置安装目标位置
+
+
+
+
+
+- 设置root密码
+
+
+
+- 下图因为密码过于简单,需要按两次完成,才可以设置成功!
+
+
+
+- 点击开始安装
+
+
+
+- 点击重启系统
+
+
+
+# 4. 系统使用
+
+重启之后就进入 RockyLinux 系统的界面,没有图形化,只有黑框框。然后我们先输入用户名`root`回车以后,在输入我们设置的密码`1`。但是输入密码的时候,是没有任何显示的,这是命令行为了保护密码的安全故意为之,我们我们输入了密码以后这直接回车即可进入系统。
+
+
+
+如果输入密码回车之后,显示`[root@localhost ~]#`那么说明我们成功进入系统
+
+最好检查一下,网络有没有问题,我们可以使用命令`ping qq.com -c 4`来测试与腾讯服务器的连通性,以此来判断网络是否正常连接。
+
+
+
+如果输出的结果如图所示,说明我们系统的网络连接正常。
+
+# 5. 快照
+
+快照可以理解为保存的一个当前状态的还原点,可以完整保存当前的环境及状态。当我们以后再实验中,不小心把环境弄坏了以后,我们可以通过拍摄的快照,时光回溯到现在这个状态,避免我们重新安装系统的麻烦。
+
+## 5.1 创建快照
+
+在创建快照的时候,一定要关机了以后再拍摄快照,不要在开机的状态下创建快照。
+
+关机命令:
+
+```shell
+poweroff
+```
+
+创建快照:
+
+在上方点击虚拟机,找到快照,拍摄快照,然后起个名字,最后点击拍摄快照。我们的快照就创建好了
+
+
+
+
+
+## 5.2 还原快照
+
+- 如果我们想要回复到某一个快照的时候,我们还是在上方虚拟机,快照,然后选择恢复到快照即可。
+
+
+
+# 6. 远程管理
+
+大多数情况下 Linux 服务器都是安装在数据中心机房的机柜里面的,大家可以把数据中心理解为大仓库,那么机柜就是一个个货架,而管理人员都是坐在办公室当中,通过电脑远程连接服务器进行管理,所以我们在后续学习的时候,为了方便,全部使用远程连接。
+
+## 6.1 安装xshell+xftp
+
+远程管理工具下载地址:https://www.xshell.com/zh/free-for-home-school/
+
+下图两个软件都需要下载安装。
+
+
+
+- 安装步骤如下图
+
+
+
+
+
+
+
+
+
+
+
+- 填写昵称和邮箱,然后Xshell装好后,一定一定要把xshell关掉,再安装xftp软件!!!!
+- xftp的安装步骤类似
+
+## 6.2 查看Linux的IP
+
+- 首先查看虚拟机的IP地址,也就是 Linux 服务器的 IP 地址,登录进虚拟机之后输入`ip address`可以查看
+
+
+
+这边可以看到本次安装的 RockyLinux 操作系统获取到的IP地址是 `192.168.173.148` 每个人装的虚拟机获取的 IP 地址可能是不一样的,需要仔细看清楚。
+
+## 6.3 xshell远程连接
+
+xshell工具只是用来远程连接和管理我们的 RockyLinux 虚拟机,所以在使用的时候,我们必须先启动 RockyLinux 虚拟机。然后再次使用 xshell 工具连接上来。并且我们在 xshell 上面执行的命令,也都会被传递到我们的 RockyLinux 上面执行。
+
+- 先在xshell上添加主机
+
+
+
+- 按照下图填写
+
+
+
+- 将密码填上去
+
+
+
+- 点击确定,然后在打开文件夹处可以看到我们刚刚添加的
+
+
+
+
+
+- 双击这个会话,就可以连接,第一次连接的时候,点击接受并保存
+
+
+
+- 之后在这里敲的命令都会被发送到Linux系统去执行
+
+
+
+
+
diff --git a/01.Linux基础/02.Linux系统安装/RL系统使用1.png b/01.Linux基础/02.Linux系统安装/RL系统使用1.png
new file mode 100644
index 0000000..cc17d0f
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/RL系统使用1.png differ
diff --git a/01.Linux基础/02.Linux系统安装/RL系统使用2.png b/01.Linux基础/02.Linux系统安装/RL系统使用2.png
new file mode 100644
index 0000000..8a3df8b
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/RL系统使用2.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144046235.png b/01.Linux基础/02.Linux系统安装/image-20251111144046235.png
new file mode 100644
index 0000000..7aa5e93
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144046235.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144109577.png b/01.Linux基础/02.Linux系统安装/image-20251111144109577.png
new file mode 100644
index 0000000..757fb48
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144109577.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144129467.png b/01.Linux基础/02.Linux系统安装/image-20251111144129467.png
new file mode 100644
index 0000000..82fdfda
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144129467.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144142613.png b/01.Linux基础/02.Linux系统安装/image-20251111144142613.png
new file mode 100644
index 0000000..9669548
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144142613.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144200630.png b/01.Linux基础/02.Linux系统安装/image-20251111144200630.png
new file mode 100644
index 0000000..e2e44d1
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144200630.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144251466.png b/01.Linux基础/02.Linux系统安装/image-20251111144251466.png
new file mode 100644
index 0000000..96c92a3
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144251466.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144307960.png b/01.Linux基础/02.Linux系统安装/image-20251111144307960.png
new file mode 100644
index 0000000..b5a58fa
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144307960.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144320341.png b/01.Linux基础/02.Linux系统安装/image-20251111144320341.png
new file mode 100644
index 0000000..64b113a
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144320341.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111144346889.png b/01.Linux基础/02.Linux系统安装/image-20251111144346889.png
new file mode 100644
index 0000000..41199c8
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111144346889.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111145856613.png b/01.Linux基础/02.Linux系统安装/image-20251111145856613.png
new file mode 100644
index 0000000..2c051c4
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111145856613.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111145907058.png b/01.Linux基础/02.Linux系统安装/image-20251111145907058.png
new file mode 100644
index 0000000..0119ec5
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111145907058.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111145922740.png b/01.Linux基础/02.Linux系统安装/image-20251111145922740.png
new file mode 100644
index 0000000..e960737
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111145922740.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111145936220.png b/01.Linux基础/02.Linux系统安装/image-20251111145936220.png
new file mode 100644
index 0000000..41d1e8d
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111145936220.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150028970.png b/01.Linux基础/02.Linux系统安装/image-20251111150028970.png
new file mode 100644
index 0000000..657d788
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150028970.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150048071.png b/01.Linux基础/02.Linux系统安装/image-20251111150048071.png
new file mode 100644
index 0000000..a99ae5d
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150048071.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150110299.png b/01.Linux基础/02.Linux系统安装/image-20251111150110299.png
new file mode 100644
index 0000000..2dab84c
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150110299.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150220296.png b/01.Linux基础/02.Linux系统安装/image-20251111150220296.png
new file mode 100644
index 0000000..f6d993c
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150220296.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150314626.png b/01.Linux基础/02.Linux系统安装/image-20251111150314626.png
new file mode 100644
index 0000000..e4914ba
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150314626.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150342548.png b/01.Linux基础/02.Linux系统安装/image-20251111150342548.png
new file mode 100644
index 0000000..55d4f3a
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150342548.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150604317.png b/01.Linux基础/02.Linux系统安装/image-20251111150604317.png
new file mode 100644
index 0000000..83198ee
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150604317.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150634635.png b/01.Linux基础/02.Linux系统安装/image-20251111150634635.png
new file mode 100644
index 0000000..549716e
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150634635.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150647727.png b/01.Linux基础/02.Linux系统安装/image-20251111150647727.png
new file mode 100644
index 0000000..92e78ba
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150647727.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150702989.png b/01.Linux基础/02.Linux系统安装/image-20251111150702989.png
new file mode 100644
index 0000000..0d04453
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150702989.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150744375.png b/01.Linux基础/02.Linux系统安装/image-20251111150744375.png
new file mode 100644
index 0000000..f6c7b10
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150744375.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111150838072.png b/01.Linux基础/02.Linux系统安装/image-20251111150838072.png
new file mode 100644
index 0000000..95576c4
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111150838072.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153004089.png b/01.Linux基础/02.Linux系统安装/image-20251111153004089.png
new file mode 100644
index 0000000..4c7123c
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153004089.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153425344.png b/01.Linux基础/02.Linux系统安装/image-20251111153425344.png
new file mode 100644
index 0000000..e51533e
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153425344.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153521001.png b/01.Linux基础/02.Linux系统安装/image-20251111153521001.png
new file mode 100644
index 0000000..3a4c90d
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153521001.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153533240.png b/01.Linux基础/02.Linux系统安装/image-20251111153533240.png
new file mode 100644
index 0000000..1c0acab
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153533240.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153545071.png b/01.Linux基础/02.Linux系统安装/image-20251111153545071.png
new file mode 100644
index 0000000..d81d6c9
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153545071.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153603651.png b/01.Linux基础/02.Linux系统安装/image-20251111153603651.png
new file mode 100644
index 0000000..73d7a7b
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153603651.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153633632.png b/01.Linux基础/02.Linux系统安装/image-20251111153633632.png
new file mode 100644
index 0000000..265cf25
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153633632.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111153828418.png b/01.Linux基础/02.Linux系统安装/image-20251111153828418.png
new file mode 100644
index 0000000..73d1c65
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111153828418.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154152950.png b/01.Linux基础/02.Linux系统安装/image-20251111154152950.png
new file mode 100644
index 0000000..ae2f4ad
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154152950.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154248793.png b/01.Linux基础/02.Linux系统安装/image-20251111154248793.png
new file mode 100644
index 0000000..7bbd3ef
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154248793.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154323546.png b/01.Linux基础/02.Linux系统安装/image-20251111154323546.png
new file mode 100644
index 0000000..d8977b7
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154323546.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154402833.png b/01.Linux基础/02.Linux系统安装/image-20251111154402833.png
new file mode 100644
index 0000000..343e17c
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154402833.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154420541.png b/01.Linux基础/02.Linux系统安装/image-20251111154420541.png
new file mode 100644
index 0000000..388466a
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154420541.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154447472.png b/01.Linux基础/02.Linux系统安装/image-20251111154447472.png
new file mode 100644
index 0000000..57b2ddb
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154447472.png differ
diff --git a/01.Linux基础/02.Linux系统安装/image-20251111154518692.png b/01.Linux基础/02.Linux系统安装/image-20251111154518692.png
new file mode 100644
index 0000000..aa7942d
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/image-20251111154518692.png differ
diff --git a/01.Linux基础/02.Linux系统安装/虚拟机快照1.png b/01.Linux基础/02.Linux系统安装/虚拟机快照1.png
new file mode 100644
index 0000000..96c7892
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/虚拟机快照1.png differ
diff --git a/01.Linux基础/02.Linux系统安装/虚拟机快照2.png b/01.Linux基础/02.Linux系统安装/虚拟机快照2.png
new file mode 100644
index 0000000..e497c1d
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/虚拟机快照2.png differ
diff --git a/01.Linux基础/02.Linux系统安装/虚拟机快照3.png b/01.Linux基础/02.Linux系统安装/虚拟机快照3.png
new file mode 100644
index 0000000..22e62a4
Binary files /dev/null and b/01.Linux基础/02.Linux系统安装/虚拟机快照3.png differ
diff --git a/01.Linux基础/03.Linux命令行.md b/01.Linux基础/03.Linux命令行.md
new file mode 100644
index 0000000..8d21104
--- /dev/null
+++ b/01.Linux基础/03.Linux命令行.md
@@ -0,0 +1,428 @@
+# 1. 初识 Shell
+
+虽然我们已经安装好了系统,但是光会安装不会操作是不够的。我们还要像玩手机一样熟悉并记忆操作方法。
+
+Shell 是系统的**用户界面**,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。实际上 Shell 是一个**命令解释器**,它解释用户输入的命令并且把用户的意图传达给内核。(可以理解为用户与内核之间的翻译官角色)
+
+
+
+我们可以使用 Shell 实现对Linux系统的大部分管理,例如:
+
+1. 文件管理
+2. 用户管理
+3. 权限管理
+4. 磁盘管理
+5. 软件管理
+6. 网络管理
+ ...
+
+使用 Shell 的两种方式
+
+- 交互式命令行
+ - 默认等待用户输入命令,输入一行回车后执行一行命令
+ - 适合少量的工作
+- Shell 脚本
+ - 将需要执行的命令和逻辑判断语句都写入一个文件后执行该文件
+ - 适合完成复杂,重复性工作
+
+# 2. Bash shell 提示符
+
+登录 Linux 系统之后,默认进入交互式的命令行界面,在光标前边会出现提示符
+
+```shell
+[root@localhost ~]#
+[用户名@主机名 目录名]权限标识
+
+```
+
+**解释说明:**
+
+- 用户名:当前登录的用户
+- 主机名:当前这台主机的名字,默认叫`localhost`
+- 目录名:当前光标所在的目录;当前用户家目录表示成`~`
+- 权限标识:超级管理员权限就表示为`#`;普通用户标识为`$`
+
+**修改提示符:**
+
+```shell
+# 这个提示符格式被`$PS1`控制,我们可以查看这个变量
+# \u表示是用户名 \h表示的是主机名 \W表示的当前所在目录 \$是权限标识
+[root@localhost ~]# echo $PS1
+[\u@\h \W]\$
+
+# 可以通过export命令修改PS1变量,让提示符可以根据你的习惯变化
+[root@localhost ~]# export PS1="{\u@\h}\W \$"
+{root@localhost}~ $
+
+# 修改回原来的样子
+{root@localhost}~ $ $export PS1="[\u@\h \W]\$ "
+
+```
+
+# 3. 常用命令
+
+**Linux 常见命令比较多,这边只列出初学者最常用的部分命令,大家可以根据命令有意去进行练习。**
+
+注意 Linux 会准确的识别出命令的大小写,所以大家需要注意大小写的问题。命令选项和参数之间是用空格进行分隔,请大家在输入的时候注意不要缺失空格。
+
+学习 Linux 最重要的就是以下三个方面
+
+1. 命令的积累
+2. 原理的掌握
+3. 大量的实战
+
+下面就是开始第一步,积累基础的命令
+
+## 3.1 ls
+
+用于显示指定工作目录下之内容(列出目前工作目录所含之文件及子目录)
+
+```shell
+Usage: ls [OPTION]... [FILE]...
+List information about the FILEs (the current directory by default).
+Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------------- |
+| `-a` | 显示所有文件及目录 (`.`开头的隐藏文件也会列出) |
+| `-l` | 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出 |
+| `-r` | 将文件以相反次序显示(原定依英文字母次序) |
+| `-t` | 将文件依建立时间之先后次序列出 |
+| `-A` | 同 `-a`,但不列出 `.(目前目录)` 及 `.. (父目录)` |
+| `-F` | 在列出的文件名称后加一符号;例如可执行档则加 `*`, 目录则加 `/`,链接加`@` |
+| `-R` | 若目录下有文件,则以下之文件亦皆依序列出 |
+| `-h` | 将显示出来的文件大小以合适的单位显示出来 |
+
+
+**案例演示**
+
+```shell
+# 查看当前目录下的文件
+[root@localhost ~]# ls
+
+# 查看根目录下的文件,查看/usr目录下的文件
+[root@localhost ~]# ls /
+[root@localhost ~]# ls /usr
+
+# 查看当前目录下所有文件,包括隐藏文件
+[root@localhost ~]# ls -a
+
+# 查看当前目录下文件详情,包括隐藏文件
+[root@localhost ~]# ls -lha
+
+# 查看 /usr/sbin/ 目录下的文件,并且显示出目录,文件,程序的区别
+# 可以看到普通文件只有文件名,可执行文件后面带*,文件夹后面带/
+[root@localhost ~]# ls -F /usr/sbin/
+
+# 查看 /etc/ssh/ 目录下的文件,如果有文件夹,那么将文件夹中的文件也显示出来
+[root@localhost ~]# ls -FR /etc/ssh/
+
+# 显示详细的信息
+[root@localhost ~]# ls -FRl
+```
+
+## 3.2 cd
+
+用于切换当前工作目录
+
+```shell
+cd: cd [-L|[-P [-e]] [-@]] [dir]
+ Change the shell working directory.
+```
+
+**案例演示**
+
+```shell
+# 跳转到 /usr/bin 目录下
+[root@localhost ~]# cd /usr/bin
+
+# 跳到自己的 home 目录
+[root@localhost bin]# cd ~
+
+# 跳到目前目录的上一层
+[root@localhost ~]# cd ..
+```
+
+## 3.3 pwd
+
+显示工作目录
+
+```shell
+pwd: pwd [-LP]
+ Print the name of the current working directory.
+```
+
+## 3.4 clear
+
+用于清除屏幕
+
+```shell
+Usage: clear [options]
+```
+
+## 3.5 echo
+
+用于字符串的输出
+
+```shell
+echo [option]... [string]...
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------- |
+| `-n` | 不输出行尾的换行符 |
+| `-e` | 允许对下面列出的加反斜线转义的字符进行解释 |
+| `\\` | 反斜线 |
+| `\a` | 报警符(BEL) |
+| `\b` | 退格符 |
+| `\c` | 禁止尾随的换行符 |
+| `\f` | 换页符 |
+| `\n` | 换行符 |
+| `\r` | 回车符 |
+| `\t` | 水平制表符 |
+| `\v` | 纵向制表符 |
+| `-E` | 禁止对在 STRINGs 中的那些序列进行解释 |
+
+**案例演示**
+
+```shell
+# 显示出 hello world
+[root@localhost ~]# echo "hello world"
+# 用两行显示出 hello world
+[root@localhost ~]# echo -e "hello\nworld"
+# 输出 hello world 的时候让系统发出警报音
+[root@localhost ~]# echo -e "hello\aworld"
+
+```
+
+
+# 4. 系统命令
+
+## 4.1 poweroff
+
+用于关闭计算器并切断电源
+
+```shell
+poweroff [OPTIONS...]
+Power off the system.
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------------- |
+| `-n` | 这个选项用于在关机时不执行文件系统的同步操作,即不调用 `sync()` 系统调用。通常,系统在关机时会自动同步所有挂载的文件系统,以确保所有挂起的磁盘写入操作都完成,从而避免数据丢失。使用 `-n` 参数可以跳过这个同步过程。 |
+| `-w` | 仅记录关机信息到 `/var/log/wtmp` 文件中,但并不实际执行关机操作。 |
+| `-d` | 不把记录写到 /var/log/wtmp 文件里 |
+| `-f` | 强制关机。此参数会立即停止所有进程并关闭系统,而不是正常关机流程。 |
+
+## 4.2 reboot
+
+用来重新启动计算机
+
+```shell
+reboot [OPTIONS...] [ARG]
+Reboot the system
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------------- |
+| `-n` | 这个选项用于在关机时不执行文件系统的同步操作,即不调用 `sync()` 系统调用。通常,系统在关机时会自动同步所有挂载的文件系统,以确保所有挂起的磁盘写入操作都完成,从而避免数据丢失。使用 `-n` 参数可以跳过这个同步过程。 |
+| `-w` | 仅记录重启信息到 `/var/log/wtmp` 文件中,但并不实际执行重启操作。 |
+| `-d` | 不把记录写到 /var/log/wtmp 档案里(-n 这个参数包含了 -d) |
+| `-f` | 强迫重开机,不呼叫 shutdown 这个指令 |
+
+
+## 4.3 whoami
+
+用于显示自身用户名称
+
+```shell
+[root@localhost ~]# whoami
+root
+
+```
+
+# 5. 快捷键
+
+| 快捷键 | 作用 |
+| :----- | :----------------------- |
+| `^C` | 终止前台运行的程序 |
+| `^D` | 退出 等价exit |
+| `^L` | 清屏 |
+| `^A` | 光标移动到命令行的最前端 |
+| `^E` | 光标移动到命令行的后端 |
+| `^U` | 删除光标前所有字符 |
+| `^K` | 删除光标后所有字符 |
+| `^R` | 搜索历史命令,利用关键词 |
+
+
+# 6. 帮助命令
+
+## 6.1 history
+
+```shell
+history [n] n为数字,列出最近的n条命令
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :------------------------------------------------------- |
+| `-c` | 将目前shell中的所有history命令消除 |
+| `-a` | 将目前新增的命令写入histfiles, 默认写入`~/.bash_history` |
+| `-r` | 将histfiles内容读入到目前shell的history记忆中 |
+| `-w` | 将目前history记忆的内容写入到histfiles |
+
+
+**案例演示**
+
+```shell
+# 将history的内容写入一个新的文件中
+[root@localhost ~]# history -w histfiles.txt
+# 清理所有的history记录,注意并不清空 ~/.bash_history 文件
+[root@localhos t ~]# history -c
+[root@localhost ~]# history
+ 1 history
+ 2 cat .bash_history
+ 3 ping -c 3 baidu.com
+ 4 history
+# 这里是执行第三条命令的意思
+[root@localhost ~]# !3
+# 从最近的命令查到以`command`开头的命令执行
+[root@localhost ~]# !ping
+# 执行上一条命令
+[root@localhost ~]# !!
+
+```
+
+## 6.2 help
+
+显示命令的帮助信息
+
+```shell
+help [-dms] [内置命令]
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :-------------------------------------------- |
+| `-d` | 输出每个主题的简短描述 |
+| `-m` | 以伪 man 手册的格式显示使用方法 |
+| `-s` | 为每一个匹配 PATTERN 模式的主题仅显示一个用法 |
+
+**案例演示**
+
+```shell
+# 查看echo的帮助信息
+[root@localhost ~]# help echo
+```
+
+## 6.3 man
+
+显示在线帮助手册页
+
+```shell
+man 需要帮助的命令或者文件
+```
+
+**快捷键**
+
+| 按键 | 用途 |
+| :---------- | :--------------------------------- |
+| `空格键` | 向下翻一页 |
+| `PaGe down` | 向下翻一页 |
+| `PaGe up` | 向上翻一页 |
+| `home` | 直接前往首页 |
+| `end` | 直接前往尾页 |
+| `/` | 从上至下搜索某个关键词,如“/linux” |
+| `?` | 从下至上搜索某个关键词,如“?linux” |
+| `n` | 定位到下一个搜索到的关键词 |
+| `N` | 定位到上一个搜索到的关键词 |
+| `q` | 退出帮助文档 |
+
+
+**手册的结构**
+
+| 结构名称 | 代表意义 |
+| :---------- | :----------------------- |
+| NAME | 命令的名称 |
+| SYNOPSIS | 参数的大致使用方法 |
+| DESCRIPTION | 介绍说明 |
+| EXAMPLES | 演示(附带简单说明) |
+| OVERVIEW | 概述 |
+| DEFAULTS | 默认的功能 |
+| OPTIONS | 具体的可用选项(带介绍) |
+| ENVIRONMENT | 环境变量 |
+| FILES | 用到的文件 |
+| SEE ALSO | 相关的资料 |
+| HISTORY | 维护历史与联系方式 |
+
+## 6.4 alias
+
+用于设置指令的别名
+
+**案例演示**
+
+```shell
+# 查看系统当前的别名
+[root@localhost ~]# alias
+alias cp='cp -i'
+alias egrep='egrep --color=auto'
+alias fgrep='fgrep --color=auto'
+alias grep='grep --color=auto'
+alias l.='ls -d .* --color=auto'
+alias ll='ls -l --color=auto'
+alias ls='ls --color=auto'
+alias mv='mv -i'
+alias rm='rm -i'
+alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
+[root@localhost ~]# ll
+总用量 4
+-rw-------. 1 root root 1241 8月 22 2018 anaconda-ks.cfg
+drwxr-xr-x. 2 root root 19 8月 21 12:15 home
+# 查看命令类型
+# ls 是 `ls --color=auto' 的别名
+# ls 是 /usr/bin/ls
+[root@xwz ~]# type -a ls
+# 修改别名,比如使用wl来查看IP地址相关信息
+[root@localhost ~]# alias wl='ip address'
+[root@localhost ~]# wl
+# 为了让别名永久生效,可以将修改别名的命令写入 bashrc 文件,这个文件中的命令会在每次登陆命令行的时候执行
+[root@localhost ~]# echo "alias wl='ip address'" >> /etc/bashrc
+
+```
+
+# 7. 环境变量
+
+环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
+
+简单的理解就是告诉操作系统在程序运行的时候,有一些默认的设置是什么。
+
+比如上面我们修改了 `LANG` 变量,就是一个环境变量,会影响到显示的语言是中文还是英文。
+
+比如在讲解 `pwd` 命令的时候,我们修改了 `$PWD` 变量,就影响了当前所处的文件夹。
+
+在我们使用 shell 命令行输入命令的时候,其实每个命令都是有一个可执行文件去完成我们下达的任务,这个可执行文件在操作系统中是分布在不同的文件夹中的,我们总不能每次执行的时候都要告诉操作系统这个文件在哪里,那么就算是查看一个文件,我们都需要输入如下的命令:
+
+```shell
+# 在Linux中,ls的可执行程序在/usr/bin目录下
+[root@localhost ~]# /usr/bin/ls -lh
+```
+
+这样就太麻烦了,所以就指定了一个环境变量 `$PATH`,这个变量中有很多的目录地址,当我们执行命令的时候,操作系统就会到这些目录中查找,是否存在你所输入的命令。如果有那么就会去执行。
+
+```shell
+[root@localhost ~]# echo $PATH
+/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
+```
+
+如果你想让自己安装的某个软件可以在操作系统的任意位置直接输入文件名执行,那么你也可以把自定义的目录加入到这个 `$PATH` 中
\ No newline at end of file
diff --git a/01.Linux基础/03.Linux命令行/命令解释器.png b/01.Linux基础/03.Linux命令行/命令解释器.png
new file mode 100644
index 0000000..66b920e
Binary files /dev/null and b/01.Linux基础/03.Linux命令行/命令解释器.png differ
diff --git a/01.Linux基础/04.文件管理.md b/01.Linux基础/04.文件管理.md
new file mode 100644
index 0000000..90aae53
--- /dev/null
+++ b/01.Linux基础/04.文件管理.md
@@ -0,0 +1,526 @@
+我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。
+
+其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们。
+
+在开始本教程前我们需要先知道什么是绝对路径与相对路径。
+
+* 绝对路径
+ * 路径的写法,由根目录`/`写起,例如:`/usr/share/doc`这个目录
+* 相对路径
+ * 路径的写法,不是由`/`写起,例如由`/usr/share/doc`要到`/usr/share/man`底下时,可以写成:`cd ../man`这就是相对路径的写法。
+
+# 1. 文件管理命令
+
+几个常见的处理目录的命令
+
+* ls(英文全拼:list files): 列出目录及文件名
+* cd(英文全拼:change directory):切换目录
+* pwd(英文全拼:print work directory):显示目前的目录
+* mkdir(英文全拼:make directory):创建一个新的目录
+* rmdir(英文全拼:remove directory):删除一个空的目录
+* cp(英文全拼:copy file): 复制文件或目录
+* rm(英文全拼:remove): 删除文件或目录
+* mv(英文全拼:move file): 移动文件与目录,或修改文件与目录的名称
+* touch: 用于创建一个新的文件
+
+## 1.1 touch
+
+创建新文件:用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的文件。
+
+```shell
+touch 文件名
+```
+
+**案例演示**
+
+```shell
+# 创建新空白文件
+[root@localhost ~]# touch newfile
+```
+
+## 1.2 mkdir
+
+创建新目录
+
+```shell
+mkdir [-mpv] 目录名称
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :--------------------------------------------------- |
+| `-m` | 配置文件的权限,直接配置,不需要看默认权限 (umask) |
+| `-p` | 帮助你直接将所需要的目录(包含上一级目录)递归创建起来 |
+| `-v` | 显示目录创建的过程 |
+
+
+**案例演示**
+
+```shell
+# 创建一个新的文件夹叫dir
+[root@localhost ~]# mkdir dir
+# 无法直接创建多层目录
+[root@localhost ~]# mkdir a/b/c
+mkdir: 无法创建目录"a/b/c": 没有那个文件或目录
+# 加上-p选项之后可以自动创建父级目录
+[root@localhost ~]# mkdir -p a/b/c
+# 显示详细的创建过程
+[root@localhost ~]# mkdir -pv dir1/dir2
+mkdir: 已创建目录 "dir1"
+mkdir: 已创建目录 "dir1/dir2"
+
+```
+
+## 1.3 cp
+
+拷贝文件和目录
+
+```shell
+cp [选项]... 源文件... 目录
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------------- |
+| `-a` | 相当于`-pdr `的意思,至于` pdr` 请参考下列说明 |
+| `-d` | 如果源文件是符号链接,则复制链接本身,而不是链接指向的文件 |
+| `-f` | 为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次 |
+| `-i` | 若目标档(destination)已经存在时,在覆盖时会先询问动作的进行 |
+| `-l` | 复制符号链接指向的文件,而不是链接本身 |
+| `-p` | 连同文件的属性一起复制过去,保持文件的原始属性(如时间戳、权限等) |
+| `-r` | 递归持续复制,用於目录的复制行为 |
+| `-u` | 仅在源文件比目标文件新或目标文件不存在时进行复制 |
+| `-v` | 显示复制的详细过程 |
+
+
+**案例演示***
+
+```shell
+[root@localhost ~]# mkdir /home/dir{1,2}
+[root@localhost ~]# touch install.log
+# 复制文件到目录下
+[root@localhost ~]# cp -v install.log /home/dir1
+# 复制文件到目录下,并且重命名为abc.txt
+[root@localhost ~]# cp -v install.log /home/dir1/abc.txt
+# 复制目录
+[root@localhost ~]# cp -rv /etc /home/dir1
+# 将多个文件复制到同一个目录
+[root@localhost ~]# cp -rv /etc/passwd /etc/hostname /home/dir2
+# 将多个文件复制到当前目录
+[root@localhost ~]# cp -rv /etc/passwd /etc/hostname .
+# 备份文件
+[root@localhost ~]# cp -rv install.log{,-old}
+
+```
+
+## 1.4 mv
+
+移动文件与目录,或修改名称
+
+```shell
+mv [选项]... 源文件... 目录
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :--------------------------------------------------------- |
+| `-f` | force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖 |
+| `-i` | 若目标文件 (destination) 已经存在时,就会询问是否覆盖 |
+| `-u` | 若目标文件已经存在,且 source 比较新,才会升级 (update) |
+| `-v` | 显示复制的详细过程 |
+
+
+**常用实例**
+
+```shell
+# 将file1移动到/home/dir2
+[root@localhost ~]# touch file1
+[root@localhost ~]# mv file1 /home/dir2
+# 将file2移动到/home/dir2,并且改名file20
+[root@localhost ~]# touch file2
+[root@localhost ~]# mv file2 /home/dir2/file20
+# 将file改名为file.txt
+[root@localhost ~]# mv file file.txt
+
+```
+
+## 1.5 rm
+
+删除文件或目录
+
+```shell
+rm [选项]... 文件...
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------- |
+| `-f` | 就是 force 的意思,忽略不存在的文件,不会出现警告信息 |
+| `-i` | 互动模式,在删除前会询问使用者是否动作 |
+| `-r` | 递归删除啊!最常用在目录的删除了!这是非常危险的选项! |
+
+**案例演示**
+
+```shell
+[root@localhost ~]# cd /home
+[root@localhost home]# rm -rf dir1
+```
+
+## 1.6 禁忌命令
+
+如下命令会从根目录开始删除Linux系统中所有的文件,包括系统文件。严令禁止在任何服务器上输入如下命令
+
+```sh
+# 不要操作!!!
+[root@localhost ~]# rm -rf /*
+```
+
+# 2. 文本文件查看
+
+在Linux中一切皆文件,说的就是Linux利用文本文件来保存系统所有的设置。
+
+我们在Linux中想实现一个功能,不可避免的需要查看文本文件,修改文本文件。
+
+## 2.1 cat
+
+用于打开文本文件并显示出来
+
+```shell
+cat [选项]... [文件]...
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :--- | :------------------------------------------------- |
+| `-n` | 由 1 开始对所有输出的行数编号 |
+| `-b` | 和 -n 相似,只不过对于空白行不编号 |
+| `-s` | 当遇到有连续两行以上的空白行,就代换为一行的空白行 |
+| `-A` | 显示控制字符 |
+
+**案例演示***
+
+```shell
+# 查看anaconda-ks.cfg文件
+[root@localhost ~]# cat anaconda-ks.cfg
+# 查看anaconda-ks.cfg文件,并且显示行号
+```
+
+## 2.2 less
+
+可以随意浏览文件,支持翻页和搜索,支持向上翻页和向下翻页
+
+**案例演示**
+
+```shell
+[root@localhost ~]# less anaconda-ks.cfg
+```
+
+## 2.3 head
+
+查看文件的开头部分的内容
+
+```shell
+head [选项]... [文件]...
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :----- | :--------------------- |
+| `-q` | 隐藏文件名,默认是隐藏 |
+| `-v` | 显示文件名 |
+| `-c N` | 显示的字节数 |
+| `-n N` | 显示的行数 |
+
+**案例演示**
+
+```shell
+# 查看文件的前6行
+[root@localhost ~]# head -n 6 anaconda-ks.cfg
+```
+
+## 2.4 tail
+
+会把文本文件里的最尾部的内容显示在屏幕上
+
+```shell
+tail [选项]... [文件]...
+```
+
+**常用选项**
+
+| 选项 | 含义 |
+| :----- | :----------------------------------- |
+| `-f` | 循环读取 |
+| `-q` | 隐藏文件名,默认隐藏 |
+| `-v` | 显示文件名 |
+| `-c N` | 显示的字节数 |
+| `-n N` | 显示文件的尾部 n 行内容 |
+| `-s` | 与-f合用,表示在每次反复的间隔休眠S秒 |
+
+
+**案例演示**
+
+```shell
+# 查看文件anaconda-ks.cfg尾部的3行
+[root@localhost ~]# tail -n 3 anaconda-ks.cfg
+# 查看日志的实时更新情况
+[root@localhost ~]# tail -f /var/log/messages
+# ctrl+c退出
+# 查看文件anaconda-ks.cfg从第10行到结尾
+[root@localhost ~]# tail -n +10 anaconda-ks.cfg
+
+```
+
+## 2.5 grep
+
+针对文件内容进行过滤,本工具属于文本三剑客,后续会详细讲解,目前只要求初学者掌握最基本的实例即可
+
+**案例演示**
+
+```shell
+# 在/etc/passwd的文件中找出有root的行
+[root@xwz ~]# grep 'root' /etc/passwd
+# 在/etc/passwd中找出root开头的行
+[root@xwz ~]# grep '^root' /etc/passwd
+# 在/etc/passwd中找出bash结尾的行
+[root@xwz ~]# grep 'bash$' /etc/passwd
+
+```
+
+# 3. 文本文件编辑
+
+在 Linux 中只掌握文本查看是远远不够的,我们还需要掌握编辑文本文件。
+
+Linux 上也有图形化的文本编辑器,类似于 Windows 的记事本,但是很多时候我们只能用命令行来管理 Linux 操作系统,所以必须要掌握命令行的文本编辑器软件。
+
+目前常见的命令行文本编辑器
+
+* **nano**:在 Debain 系列的系统上会比较常见,但是其他的 Linux 发行版也都可以安装
+* **vi**:所有的 Unix Like 系统都会内建 vi 文本编辑器,其他的文本编辑器则不一定会存在。
+* **vim**:具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。
+
+
+## 3.1 什么是 Vim
+
+Vim 是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
+
+Vim 是一个纯命令行文本编辑器,很多文本编辑的功能都是通过键盘快捷键的方式完成,所以我们需要记住常用的键位。
+
+
+
+## 3.2 使用方式
+
+基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode),输入模式(Insert mode)和末行模式(Last line mode)。 这三种模式的作用分别是:
+
+### 3.2.1 命令模式
+
+用户刚刚启动 vi/vim,便进入了命令模式。
+
+此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下`i`,并不会输入一个字符,`i`被当作了一个命令。
+
+以下是常用的几个命令:
+
+| 命令 | 含义 |
+| :--- | :----------------------------------- |
+| `i` | 切换到输入模式,以输入字符 |
+| `x` | 删除当前光标所在处的字符 |
+| `:` | 切换到末行模式,以在最底一行输入命令 |
+
+### 3.2.2 输入模式
+
+在命令模式下按下 `i` 就进入了输入模式。
+
+在输入模式中,可以使用以下按键:
+
+| 命令 | 含义 |
+| :---------------------- | :--------------------------------------------- |
+| `字符按键以及Shift组合` | 输入字符 |
+| `ENTER` | 回车键,换行 |
+| `BACK SPACE` | 退格键,删除光标前一个字符 |
+| `DEL` | 删除键,删除光标后一个字符 |
+| `方向键` | 在文本中移动光标 |
+| `HOME/END` | 移动光标到行首/行尾 |
+| `Page Up/Page Down` | 上/下翻页 |
+| `Insert` | 切换光标为输入/替换模式,光标将变成竖线/下划线 |
+| `ESC` | 退出输入模式,切换到命令模式 |
+
+### 3.2.3 末行模式
+
+在命令模式下按下 `:`(英文冒号)就进入了末行模式。
+
+末行模式可以输入单个或多个字符的命令,可用的命令非常多。
+
+在末行模式中,基本的命令有:
+
+| 命令 | 含义 |
+| :--- | :------- |
+| `q` | 退出程序 |
+| `w` | 保存文件 |
+
+按 ESC 键可随时退出末行模式。
+
+简单的说,我们可以将这三个模式的关系用下图来表示:
+
+
+
+## 3.3 使用实例
+
+有些 linux 发行套件上并没有安装 vim,我们可以安装一下,下面提供了 Rockylinux 的安装命令
+
+```shell
+# yum是在线安装软件的命令,后面会有详细的介绍,这边直接使用
+[root@localhost ~]# yum -y install vim
+
+```
+
+vi和vim大部分的操作完全一模一样,所以会使用vim自然也会使用vi
+
+**案例演示**
+
+直接输入`vim 文件名`就能够进入 vim 的命令模式了。请注意,记得 vim 后面一定要加文件名,不管该文件存在与否!
+
+```shell
+[root@localhost ~]# vim file.txt
+```
+
+输入这条命令之后,会看到如下画面
+
+
+
+按下`i`进入输入模式(也称为编辑模式),开始编辑文字
+
+在命令模式之中,只要按下`i`,`o`,`a`等字符就可以进入输入模式了!
+
+在编辑模式当中,你可以发现在左下角状态栏中会出现`--INSERT--`的字样,那就是可以输入任意字符的提示。
+
+这个时候,键盘上除了 Esc 这个按键之外,其他的按键都可以视作为一般的输入按钮了,所以你可以进行任何的编辑。
+
+
+
+好了,假设我已经按照上面的样式给他编辑完毕了,那么应该要如何退出呢?是的!没错!就是给他按下 Esc 这个按钮即可!马上你就会发现画面左下角`--INSERT--`的不见了!
+
+
+
+输入**:wq**后回车即可保存离开,注意其中的冒号必须是英文输入法下的冒号!
+
+
+
+现在我们就成功创建了一个文件,查看文件的内容吧
+
+```shell
+[root@localhost ~]# ls -lh file.txt
+[root@localhost ~]# cat file.txt
+```
+
+## 3.4 按键说明
+
+下面将会列举出 vim 非常多的常用按键,初学者只需要浏览一遍,记住大概 vim 有哪些功能,等后面大量使用 vim 的时候,再来翻阅笔记,并且在多次使用中把这些功能记住。
+
+### 3.4.1 命令模式
+
+下面的操作都是在命令模式下进行的
+
+**移动光标的方法**
+
+| 方法 | 含义 |
+| :------------------- | :----------------------------------------------------------- |
+| `h 或 向左箭头键(←)` | 光标向左移动一个字符 |
+| `j 或 向下箭头键(↓)` | 光标向下移动一个字符 |
+| `k 或 向上箭头键(↑)` | 光标向上移动一个字符 |
+| `l 或 向右箭头键(→)` | 光标向右移动一个字符 |
+| `[Ctrl] + [f]` | 屏幕『向下』移动一页,相当于 [Page Down]按键 (常用) |
+| `[Ctrl] + [b]` | 屏幕『向上』移动一页,相当于 [Page Up] 按键 (常用) |
+| `[Ctrl] + [d]` | 屏幕『向下』移动半页 |
+| `[Ctrl] + [u]` | 屏幕『向上』移动半页 |
+| `+` | 光标移动到非空格符的下一行 |
+| `-` | 光标移动到非空格符的上一行 |
+| `n + [space]` | 那个 n 表示『数字』,例如 20 。按下数字后再按空格键,光标会向右移动这一行的 n 个字符。例如 20 则光标会向后面移动 20 个字符距离。 |
+| `0 或功能键[Home]` | 移动到这一行的最前面字符处 |
+| `$ 或功能键[End]` | 移动到这一行的最后面字符处 |
+| `H ` | 光标移动到这个屏幕的最上方那一行的第一个字符 |
+| `M` | 光标移动到这个屏幕的中央那一行的第一个字符 |
+| `L` | 光标移动到这个屏幕的最下方那一行的第一个字符 |
+| `G` | 移动到这个档案的最后一行(常用) |
+| `nG` | n 为数字。移动到这个文档的第 n 行。例如 20G 则会移动到这个档案的第 20 行 |
+| `gg` | 移动到这个档案的第一行,相当于 1G |
+| `n + [Enter]` | n 为数字。光标向下移动 n行 |
+
+**文本的搜索与替换**
+
+| 方法 | 含义 |
+| :--------------------------------------------- | :----------------------------------------------------------- |
+| `/word ` | 向光标之下寻找一个名称为 word 的字符串。 |
+| `?word` | 向光标之上寻找一个字符串名称为 word 的字符串。 |
+| `n` | 这个 n 是英文按键。代表重复前一个搜寻的动作。 |
+| `N` | 这个 N 是英文按键。与 n 刚好相反,为『反向』进行前一个搜寻动作。 |
+| `:n1,n2s/word1/word2/g` | n1 与 n2 为数字。在第 n1 与 n2 行之间寻找 word1 这个字符串,并将该字符串取代为 word2 |
+| `:1,$s/word1/word2/g` 或 `:%s/word1/word2/g` | 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 ! |
+| `:1,$s/word1/word2/gc` 或 `:%s/word1/word2/gc` | 从第一行到最后一行寻找 word1 字符串,并将该字符串取代为 word2 !且在取代前显示提示字符给用户确认 (confirm) 是否需要取代! |
+
+**删除/剪切、复制与粘贴**
+
+| 方法 | 含义 |
+| :--------- | :----------------------------------------------------------- |
+| `x, X` | 在一行字当中,x 为向后删除一个字符 (相当于 [del] 按键), X 为向前删除一个字符(相当于 [backspace] 亦即是退格键) |
+| `nx` | n 为数字,连续向后删除 n 个字符。举例来说,我要连续删除 10 个字符, 『10x』。 |
+| `dd` | 删除/剪切光标所在的那一整行(常用) |
+| `ndd` | n 为数字。删除/剪切光标所在的向下 n 行,例如 20dd 则是删除 20 行 |
+| `d1G` | 删除光标所在到第一行的所有数据 |
+| `dG` | 删除光标所在到最后一行的所有数据 |
+| `d$` | 删除游标所在处,到该行的最后一个字符 |
+| `d0` | 那个是数字的 0 ,删除光标所在处,到该行的最前面一个字符 |
+| `yy` | 复制游标所在的那一行 |
+| `nyy` | n 为数字。复制光标所在的向下 n 行,例如 20yy 则是复制 20 行 |
+| `y1G` | 复制游标所在行到第一行的所有数据 |
+| `yG` | 复制游标所在行到最后一行的所有数据 |
+| `y0` | 复制光标所在的那个字符到该行行首的所有数据 |
+| `y$` | 复制光标所在的那个字符到该行行尾的所有数据 |
+| `p, P` | p 为将已复制的数据在光标下一行贴上,P 则为贴在光标上一行! 举例来说,我目前光标在第 20 行,且已经复制了 10 行数据。则按下 p 后, 那 10 行数据会贴在原本的 20 行之后,亦即由 21 行开始贴。但如果是按下 P 呢? 那么原本的第 20 行会被推到变成 30 行。 |
+| `J` | 将光标所在行与下一行的数据结合成同一行 |
+| `c` | 重复删除多个数据,例如向下删除 10 行,[ 10c ] |
+| `u` | 复原前一个动作。 |
+| `[Ctrl]+r` | 重做上一个动作。 |
+| `.` | 重复前一个动作。 如果你想要重复删除、重复贴上等等动作,按下小数点『.』就好了! |
+
+**进入输入或取代的编辑模式**
+
+| 方法 | 含义 |
+| :------ | :----------------------------------------------------------- |
+| `i, I` | 进入输入模式(Insert mode): i 为『从目前光标所在处输入』, I 为『在目前所在行的第一个非空格符处开始输入』。 |
+| `a, A` | 进入输入模式(Insert mode): a 为『从目前光标所在的下一个字符处开始输入』, A 为『从光标所在行的最后一个字符处开始输入』。 |
+| `o, O` | 进入输入模式(Insert mode): 这是英文字母 o 的大小写。o 为在目前光标所在的下一行处输入新的一行; O 为在目前光标所在的上一行处输入新的一行! |
+| `r, R` | 进入取代模式(Replace mode): r 只会取代光标所在的那一个字符一次;R会一直取代光标所在的文字,直到按下 ESC 为止 |
+| `[Esc]` | 退出编辑模式,回到一般模式中 |
+
+### 3.4.2 末行模式
+
+**末行模式下的储存、离开等指令**
+
+| 方法 | 含义 |
+| :-------------------- | :----------------------------------------------------------- |
+| `:w` | 将编辑的数据写入硬盘中 |
+| `:w!` | 若文件属性为『只读』时,强制写入该文件。不过,到底能不能写入, 还是跟你对该文件的权限有关 |
+| `:q` | 离开 vim |
+| `:q!` | 若曾修改过文件,又不想储存,使用 ! 为强制离开不储存。 |
+| `:wq` | 保存后离开,若为 `:wq!` 则为强制保存退出 |
+| `ZZ` | 这是大写的 Z 喔!如果修改过,保存当前文件,然后退出!效果等同于(保存并退出) |
+| `:x` | 效果等同于(保存并退出) |
+| `:X` | 大写的X,用于加密文件 |
+| `ZQ` | 不保存,强制退出。效果等同于 `:q!` |
+| `:w [filename]` | 将编辑的数据储存成另一个文件(类似文件另存为) |
+| `:r [filename]` | 在编辑的数据中,读入另一个文件的数据。亦即将 『filename』 这个文件内容加到光标所在行后面 |
+| `:n1,n2 w [filename]` | 将 n1 到 n2 的内容储存成 filename 这个文件。 |
+| `:!command` | 暂时离开 vi 到bash命令行下执行 command 的显示结果!例如 『:! ls /home』即可在 vi 当中察看 /home 底下以 ls 输出的文件信息 |
+
+**vim环境变量修改**
+
+| 方法 | 含义 |
+| :---------- | :------------------------------------------------- |
+| `:set nu` | 显示行号,设定之后,会在每一行的前缀显示该行的行号 |
+| `:set nonu` | 与 set nu 相反,为取消行号 |
\ No newline at end of file
diff --git a/01.Linux基础/04.文件管理/vim内容编辑.png b/01.Linux基础/04.文件管理/vim内容编辑.png
new file mode 100644
index 0000000..4699c52
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim内容编辑.png differ
diff --git a/01.Linux基础/04.文件管理/vim命令模式.png b/01.Linux基础/04.文件管理/vim命令模式.png
new file mode 100644
index 0000000..8ee07fc
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim命令模式.png differ
diff --git a/01.Linux基础/04.文件管理/vim末行模式.png b/01.Linux基础/04.文件管理/vim末行模式.png
new file mode 100644
index 0000000..d2b3d30
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim末行模式.png differ
diff --git a/01.Linux基础/04.文件管理/vim模式关系.png b/01.Linux基础/04.文件管理/vim模式关系.png
new file mode 100644
index 0000000..f3cbdc6
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim模式关系.png differ
diff --git a/01.Linux基础/04.文件管理/vim编辑模式.png b/01.Linux基础/04.文件管理/vim编辑模式.png
new file mode 100644
index 0000000..738b4fc
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim编辑模式.png differ
diff --git a/01.Linux基础/04.文件管理/vim键盘图.png b/01.Linux基础/04.文件管理/vim键盘图.png
new file mode 100644
index 0000000..b0d0c82
Binary files /dev/null and b/01.Linux基础/04.文件管理/vim键盘图.png differ
diff --git a/01.Linux基础/05.文件属性与查找.md b/01.Linux基础/05.文件属性与查找.md
new file mode 100644
index 0000000..d0fc589
--- /dev/null
+++ b/01.Linux基础/05.文件属性与查找.md
@@ -0,0 +1,273 @@
+# 1. 文件时间
+
+任何一个操作系统都有时间的概念,时间的概念主要用于对文件和系统中发生的时间进行记录,在 Linux 中,可以使用 stat 查看 Linux 系统中文件的时间。
+
+## 1.1 stat
+
+用于显示文件时间和 inode 内容,inode相关的知识会在后面的磁盘管理章节详细讲解,这边主要来看文件的时间
+
+```shell
+stat [选项]... 文件...
+```
+
+**案例演示**
+
+stat查看文件时间,这边为了我们方便看得懂,建议改为英文系统环境
+
+```shell
+[root@localhost ~]# export LANG="en_US.UTF-8"
+# 改回中文是LANG="zh_CN.UTF-8"
+[root@localhost ~]# stat anaconda-ks.cfg
+ File: ‘anaconda-ks.cfg’
+ Size: 1241 Blocks: 8 IO Block: 4096 regular file
+Device: fd00h/64768d Inode: 33574979 Links: 1
+Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
+Context: system_u:object_r:admin_home_t:s0
+Access: 2021-04-04 17:54:09.700844151 +0800
+Modify: 2021-04-04 16:53:30.524854041 +0800
+Change: 2021-04-04 16:53:30.524854041 +0800
+ Birth: -
+```
+
+- **Access:访问时间,也叫 atime**
+ - 当文件被访问的时候,这个时间就会发生改变
+ - Linux文件运行的时候查看文件又频繁数量又大,如果每次 atime 发生变化的时候都记入硬盘,或造成很大的压力。必须满足其中一个条件:
+ - 自上次 atime 修改后,已达到 86400 秒
+ - 发生写操作时
+- **Modify:修改时间,也叫 mtime**
+ - 当文件内容发生变化的时候,这个时间就会发生改变
+- **Change:改变时间,也叫 ctime**
+ - 当文件状态被改变的时候,这个时间就会发生修改
+
+# 2. 文件类型
+
+Linux 系统和 Windows 系统有很大的区别,Windows 系统查看文件的后缀名就可以知道这个是什么类型的文件,比如:`test.jpg` 这个是一个图片,如果你在 Windows 上双击打开,就会使用支持查看图片的软件打开。
+
+Linux 系统就根本不看文件的后缀名,你认为这个是什么文件,你就使用什么工具打开这个文件,如果打开错误,就会报错,看下面的案例
+
+```shell
+[root@localhost ~]# cat file
+cat: file: Is a directory
+```
+
+当你以为 file 是个文件,使用 cat 命令查看的时候,cat 会提示你这个是个文件夹,你才反应过来,应该使用 cd 命令打开。
+所以在 Linux 中,我们需要使用和 windows 不一样的方法来判断这个文件的类型。
+
+## 2.1 方式一:ls
+
+通过 `ls -l` 查看第一个字母:
+
+| 标识符 | 文件类型 |
+| `-` | 普通文件(文本文档,二进制文件,压缩文件,电影,图片等等)|
+| `d` | 目录文件 |
+| `b` | 块设备文件(块设备)存储设备硬盘,U盘 `/dev/sda` 和 `/dev/sda1` |
+| `c` | 字符设备文件(字符设备)打印机,终端 `/dev/tty1` 和 `/dev/zero` |
+| `s` | 套接字文件 |
+| `p` | 管道文件 |
+| `l` | 链接文件 |
+
+**案例演示**
+
+```shell
+[root@localhost ~]# type ll
+[root@localhost ~]# ll -d /etc/hosts /bin/ls /home /dev/nvme0n1 /dev/tty1 /etc/grub2.cfg /dev/log
+-rwxr-xr-x. 1 root root 140872 4月 21 2024 /bin/ls
+lrwxrwxrwx. 1 root root 28 11月 8 21:42 /dev/log -> /run/systemd/journal/dev-log
+brw-rw----. 1 root disk 259, 0 11月 8 21:42 /dev/nvme0n1
+crw--w----. 1 root tty 4, 1 11月 8 21:42 /dev/tty1
+lrwxrwxrwx. 1 root root 22 9月 5 03:00 /etc/grub2.cfg -> ../boot/grub2/grub.cfg
+-rw-r--r--. 1 root root 158 6月 23 2020 /etc/hosts
+drwxr-xr-x. 10 root root 124 11月 8 09:57 /home
+```
+
+对于初学者而言,我们现在只要知道可以通过这样的方式查看文件的类型,并且能够知道 `-` 和 `d` 的意思即可。后面在学习的过程中,会慢慢的将所有文件类型都掌握的。
+
+## 2.2 方法二:file
+
+file 是专门用来查看文件的类型的命令,有时候也可以使用
+
+**案例演示**
+
+```shell
+[root@localhost ~]# file /etc/hosts
+/etc/hosts: ASCII text
+[root@localhost ~]# file /bin/ls
+/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=ceaf496f3aec08afced234f4f36330d3d13a657b, stripped
+[root@localhost ~]# file /dev/nvme0n1
+/dev/nvme0n1: block special (259/0)
+[root@localhost ~]# file /dev/tty1
+/dev/tty1: character special
+[root@localhost ~]# file /etc/grub2.cfg
+/etc/grub2.cfg: symbolic link to `../boot/grub2/grub.cfg'
+[root@localhost ~]# file /home
+/home: directory
+[root@localhost ~]# file /run/dmeventd-client
+/run/dmeventd-client: fifo (named pipe)
+```
+
+## 2.3 方法三:stat
+
+这个命令上面已经介绍过了,在输出结果中也是可以看到文件的类型
+
+# 3. 文件查找
+
+在 windows 中可以在文件管理器中很方便的输入文件名查找文件,然而 Linux 的文件查找功能更加的方便,并且功能更加的强大。
+
+find 命令实时查找工具,通过遍历指定路径下的文件系统完成文件查找
+
+工作特点:
+
+- 查找速度略慢
+- 精确查找
+- 实时查找
+- 可以满足多种条件匹配
+
+```shell
+find [选项] [路径] [查找条件 + 处理动作]
+ 查找路径:指定具体目录路径,默认是当前文件夹
+ 查找条件:指定的查找标准(文件名/大小/类型/权限等),默认是找出所有文件
+ 处理动作:对符合条件的文件做什么操作,默认输出屏幕
+```
+
+## 3.1 查找条件
+
+根据文件名查找
+
+```shell
+[root@localhost ~]# find /etc -name "ens160.nmconnection"
+[root@localhost ~]# find /etc -iname "ens160.nmconnection" # 忽略大小写
+[root@localhost ~]# find /etc -iname "ens*"
+```
+
+按文件大小
+
+```shell
+[root@localhost ~]# find /etc -size +5M # 大于5M
+[root@localhost ~]# find /etc -size 5M # 等于5M
+[root@localhost ~]# find /etc -size -5M # 小于5M
+[root@localhost ~]# find /etc -size +5M -ls # 找到的处理动作-ls
+```
+
+指定查找的目录深度
+
+```shell
+[root@localhost ~]# find / -maxdepth 3 -a -name "ens160.nmconnection" # 最大查找深度
+# -a是同时满足,-o是或
+[root@localhost ~]# find / -mindepth 3 -a -name "ens160.nmconnection" # 最小查找深度
+```
+
+按时间找
+
+```shell
+[root@localhost ~]# find /etc -mtime +5 # 修改时间超过5天
+[root@localhost ~]# find /etc -mtime 5 # 修改时间等于5天
+[root@localhost ~]# find /etc -mtime -5 # 修改时间5天以内
+```
+
+按照文件属主、属组找,文件的属主和属组,会在下一篇详细讲解。
+
+```shell
+[root@localhost ~]# find /home -user xwz # 属主是xwz的文件
+[root@localhost ~]# find /home -group xwz
+[root@localhost ~]# find /home -user xwz -group xwz
+[root@localhost ~]# find /home -user xwz -a -group root
+[root@localhost ~]# find /home -user xwz -o -group root
+[root@localhost ~]# find /home -nouser # 没有属主的文件
+[root@localhost ~]# find /home -nogroup # 没有属组的文件
+```
+
+按文件类型
+
+```shell
+[root@localhost ~]# find /dev -type d
+```
+
+按文件权限,文件权限会在下一篇详细讲解
+
+```shell
+[root@localhost ~]# find / -perm 644 -ls
+[root@localhost ~]# find / -perm -644 -ls # 权限大于等于/包含644的
+```
+
+按正则表达式
+
+```shell
+[root@localhost ~]# find /etc -regex '.*ens[0-9][0-9][0-9].*'
+# .* 任意多个字符
+# [0-9] 任意一个数字
+```
+
+* 条件组合
+ * **-a**:多个条件and并列
+ * **-o**:多个条件or并列
+ * **-not**:条件取反
+
+## 3.2 处理动作
+
+| 动作 | 含义 |
+| :----------------------- | :------------------------------------------- |
+| `‐print` | 默认的处理动作,显示至屏幕 |
+| `-ls` | 对查找到的文件执行 `ls ‐l` 命令 |
+| `-delete` | 删除查找到的文件 |
+| `-fls /path/to/filename` | 查找到的所有文件的长格式信息保存至指定文件中 |
+| `{}` | 用于引用查找到的文件名称自身 |
+| `-exec` | 允许对找到的每个文件执行一个命令 |
+
+下面的相关案例大家学习完后续用户权限管理之后,就可以完全看的懂了
+
+## 3.3 相关案例
+
+- 查找到root目录下面以.log结尾的文件,并且复制到/home/dir1中
+
+```shell
+[root@localhost ~]# find /root -name "*.log" -exec mv {} /home/dir1 \;
+```
+
+* 查找/var目录下属主为root,且属组为mail的所有文件或目录
+
+```shell
+[root@localhost ~]# find /var -user root -group mail
+```
+
+* 查找/usr目录下不属于root,bin或ftp用户的所有文件或目录
+
+```shell
+[root@localhost ~]# find /usr -not -user root -a -not -user bin -a -not -user ftp
+[root@localhost ~]# find /usr -not \( -user root -o -user bin -o -user ftp \)
+```
+
+* 查找/etc目录下最近一周内容曾被修改过的文件或目录
+
+```shell
+[root@localhost ~]# find /etc -mtime -7
+```
+
+* 查找当前系统上没有属主或属组,且最近一周内曾被访问过的文件或目录
+
+```shell
+[root@localhost ~]# find / \( -nouser -o -nogroup \) -a -atime -7
+```
+
+* 查找/etc目录下大于1M且类型为普通文件的所有文件或目录
+
+```shell
+[root@localhost ~]# find /etc -size +1M -type f
+```
+
+* 查找/etc目录下所有用户都没有写权限的文件
+
+```shell
+[root@localhost ~]# find /etc -not -perm /222
+```
+
+* 查找/etc目录下至少一类用户没有执行权限的文件
+
+```shell
+[root@localhost ~]# find /etc -not -perm -111
+```
+
+* 查找/etc/init.d目录下,所有用户都有执行权限,且其它用户写权限的文件
+
+```shell
+[root@localhost ~]# find /etc/init.d -perm -113
+```
\ No newline at end of file
diff --git a/01.Linux基础/06.用户权限管理.md b/01.Linux基础/06.用户权限管理.md
new file mode 100644
index 0000000..c43e17a
--- /dev/null
+++ b/01.Linux基础/06.用户权限管理.md
@@ -0,0 +1,648 @@
+Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。
+
+为了更加方便的管理多个用户,就出现了用户组的概念,关于用户和用户组:
+
+* 系统上的每个进程(运行的程序)都是作为特定用户运行
+* 每个文件是由一个特定的用户拥有
+* 访问文件和目录受到用户的限制
+* 与正在运行的进程相关联的用户确定该进程可访问的文件和目录
+
+实现用户账号的管理,要完成的工作主要有如下几个方面:
+
+* 用户账号的添加、删除与修改
+* 用户口令的管理
+* 用户组的管理
+
+# 1. 用户和用户组查看
+
+## 1.1 id
+
+用于显示用户的ID,以及所属群组的 ID
+
+id会显示用户以及所属群组的实际与有效 ID。若两个 ID 相同,则仅显示实际 ID。若仅指定用户名称,则显示目前用户的 ID。
+
+```shell
+id [OPTION]... [USER]
+```
+
+| 选项 | 含义 |
+| :--- | :---------------------------------------------------------- |
+| `-g` | 显示用户所属群组的 ID |
+| `-G` | 显示用户所属附加群组的 ID |
+| `-n` | 显示用户,所属群组或附加群组的名称 |
+| `-r` | 显示用户真实 ID,用户真实的 uid |
+| `-u` | 显示用户有效 ID,可以都某些高权限用户,通过有效 id 限制权限 |
+
+### 1.1.1 uid 约定
+
+Linux 操作系统会依据用户的 uid 数值来判定这个用户的角色,分别如下
+
+- **0**:超级管理员,也就是root,在linux系统中拥有所有权力
+- **1~999**:系统用户,系统用户往往是用来约束系统中的服务的
+- **1000+**:普通用户,可以用来登陆和使用Linux操作系统
+
+关于root用户
+
+- uid是0
+- 拥有操作系统所有权力
+- 该用户有权力覆盖文件系统上的普通权限
+- 安装或删除软件并管理系统文件和目录
+- 大多数设备只能由root控制
+
+### 1.1.2 案例演示
+
+查看当前登陆的用户信息
+
+```shell
+[root@localhost ~]# id
+uid=0(root) gid=0(root) 组=0(root) 环境=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+```
+
+查看文件的拥有者
+
+```shell
+[root@localhost ~]# ll anaconda-ks.cfg
+-rw-------. 1 root root 1241 4月 4 16:53 anaconda-ks.cfg
+```
+
+
+
+查看运行进程的用户名,ps命令会在后面进程管理部分讲解
+
+```shell
+[root@localhost ~]# ps aux
+USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+root 2 0.0 0.0 0 0 ? S 09:06 0:00 [kthreadd]
+root 3 0.0 0.0 0 0 ? S 09:06 0:01 [ksoftirqd/0]
+root 4 0.1 0.0 0 0 ? R 09:06 0:09 [kworker/0:0]
+root 5 0.0 0.0 0 0 ? S< 09:06 0:00 [kworker/0:0H]
+```
+
+## 1.2 相关的文件
+
+之前说过 Linux 一切皆文件,所以用户和用户组相关的信息也都是保存在文本文件中的,下面列举出相关的文件。
+
+### 1.2.1 passwd 文件
+
+用于保存用户的信息,一般第一行是 root 用户,下面都是其他用户
+
+```shell
+[root@localhost ~]# head -n 1 /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+# 这个格式为用户名:密码:uid:gid:描述:家目录:登陆后执行的命令
+```
+
+### 1.2.2 shadow 文件
+
+格式中密码占位置太长了,所以使用x来替代,Linux系统会到shadow中查找x部分的的密码内容
+
+```shell
+[root@localhost ~]# head -n 1 /etc/shadow
+root:$6$frokclXSnQa8EbKs$pWElbjPlmxjYh30tr8qLsTQVOhuPg7GmW9Sanm2yXAK8TNMgje1gyc/vwPgqvmSMf6VaoEvveM0gFvtETmXy/.::0:99999:7:::
+# 这个格式为用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段
+```
+
+格式不需要大家记住,只需要知道关于这个用户的密码和有效期都在这个文件中即可。
+
+密码在`passwd`文件中会使用加密算法加密,所以别想知道我的密码是什么,加密算法默认是`$6`,这个类型6的加密算法是sha-512。我们也可以在man手册中看到对shadow文件的详细解释。
+
+```shell
+[root@localhost ~]# man 5 shadow
+# man手册一个有9个章节,其中第5个章节是对文件格式的说明
+# 对man手册感兴趣的同学,也可以自己在网上查找学习man手册的更多内容
+```
+
+### 1.2.3 group文件
+
+用户和组的对应关系,会保存在group文件中
+
+```shell
+[root@localhost ~]# head -n 1 /etc/group
+root:x:0:
+# 这个格式是组名:口令:组标识号:组内用户列表
+```
+
+# 2. 用户组管理
+
+## 2.1 添加用户组
+
+groupadd 命令用于创建一个新的工作组,新工作组的信息将被添加到系统文件中
+
+```shell
+groupadd [选项] 组
+```
+
+### 2.1.1 常用选项
+
+| 选项 | 含义 |
+| :--- | :----------------------------------------------------------- |
+| `-g` | 指定新建工作组的 id |
+| `-r` | 创建系统工作组,系统工作组的组ID小于 500 |
+| `-K` | 覆盖配置文件`/etc/login.defs` |
+| `-o` | 允许添加组 ID 号不唯一的工作组 |
+| `-f` | 如果指定的组已经存在,此选项将失明了仅以成功状态退出。当与 -g 一起使用,并且指定的GID_MIN已经存在时,选择另一个唯一的GID(即-g关闭) |
+
+### 2.1.2 案例演示
+
+按照下图创建组,并且指定gid,并且检查是否成功
+
+
+
+```shell
+[root@localhost ~]# groupadd hr -g 1000
+[root@localhost ~]# groupadd sale -g 2000
+[root@localhost ~]# groupadd it -g 3000
+[root@localhost ~]# groupadd fd -g 4000
+[root@localhost ~]# tail -n 4 /etc/group
+hr:x:1000:
+sale:x:2000:
+it:x:3000:
+fd:x:4000:
+```
+
+## 2.2 修改用户组
+
+groupmod命令用于更改群组识别码或名称
+
+```shell
+groupmod [选项] 组
+```
+
+### 2.2.1 常用选项
+
+- **-g**:将组 ID 改为 GID
+- **-n**:改名为 NEW_GROUP
+- **-o**:允许使用重复的 GID
+
+### 2.2.2 案例演示
+
+* 修改fd组的名字为finance
+
+```shell
+[root@localhost ~]# groupmod -n finance fd
+[root@localhost ~]# tail -n 1 /etc/group
+finance:x:4000:
+```
+
+## 2.3 删除用户组
+
+groupdel命令用于删除群组
+
+需要从系统上删除群组时,可用groupdel(group delete)指令来完成这项工作。倘若该群组中仍包括某些用户,则必须先删除这些用户后,方能删除群组。
+
+```shell
+groupdel [组名]
+```
+
+### 2.3.1 案例演示
+
+* 删除一个用户组
+
+```shell
+[root@localhost ~]# groupadd test
+[root@localhost ~]# groupdel test
+```
+
+## 2.4 用户组成员管理
+
+gpasswd 是 Linux 下工作组文件 /etc/group 和 /etc/gshadow 管理工具,用于将一个用户添加到组或者从组中删除
+
+```shell
+gpasswd [选项] 组
+```
+
+### 2.4.1 常用选项
+
+- **-a**:添加用户到组;
+- **-d**:从组删除用户;
+- **-A**:指定管理员,可以执行添加或者删除组员;
+- **-M**:替换组中的全部用户列表,不包含在内的用户将会从组中删除;
+- **-R**:限制用户登入组,只有组中的成员才可以用newgrp加入该组。
+
+### 2.4.2 案例演示
+
+创建用户 itadmin,并且将其加入 it 组
+
+```shell
+[root@localhost ~]# useradd itadmin
+[root@localhost ~]# gpasswd -a itadmin it
+正在将用户“itadmin”加入到“it”组中
+[root@localhost ~]# cat /etc/group |grep it:
+it:x:3000:itadmin
+# 在组文件中,可以看到这个组的成员
+[root@localhost ~]# id itadmin
+uid=6667(itadmin) gid=6667(itadmin) 组=6667(itadmin),3000(it)
+# 在用户的信息中,可以看到这个用户的所属组
+```
+
+# 3. 用户管理
+
+## 3.1 添加用户
+
+useradd 可以用来添加新的用户账号
+
+```shell
+useradd [选项] 用户名
+```
+
+### 3.1.1 常用选项
+
+* **-c comment**:指定一段注释性描述。
+* **-d 目录**:指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。
+* **-m**:创建用户的主目录
+* **-g 用户组**:指定用户所属的用户组,默认会创建一个和用户名同名的用户组。
+* **-G 用户组**:用户组 指定用户所属的附加组,一个用户可以属于多个附加组。
+* **-s Shell文件**:指定用户的登录Shell。
+* **-u 用户号**:指定用户的用户号,如果同时有-o选项,则可以重复使用其他用户的标识号。
+
+### 3.1.2 案例演示
+
+* 添加一般用户
+
+```shell
+[root@localhost ~]# useradd user01
+```
+
+* 为添加的用户指定相应的用户组
+
+```shell
+[root@localhost ~]# useradd -g root user02
+```
+
+* 为新添加的用户指定home目录
+
+```shell
+[root@localhost ~]# useradd -d /home/test user03
+```
+
+* 建立一个不给登录的用户
+
+```shell
+[root@localhost ~]# useradd -s /sbin/nologin user04
+```
+
+- 查看用户描述信息
+
+```bash
+[root@localhost ~]# useradd -c "this is python_developmer user" python-developmer
+[root@localhost ~]# cat /etc/passwd |grep python-developmer
+python-developmer:x:1005:1005:this is python_developmer user:/home/python-developmer:/bin/bash
+```
+
+## 3.2 切换用户
+
+su命令用户Linux系统中的用户切换
+
+```BASH
+su [选项] 用户名
+```
+
+### 3.2.1 常用选项
+
+- `-`:以目标用户的环境变量启动新会话。这将模拟用户完全登录到新用户账户,包括其家目录、环境变量等。
+- `-c 命令`:执行指定的命令,并在执行完毕后返回原始用户。
+- `-s shell`:使用指定的 shell 替代目标用户的默认 shell。
+
+## 3.3 修改用户:usermod
+
+usermod命令用于修改用户帐号
+
+usermod可用来修改用户帐号的各项设定
+
+```shell
+usermod [选项] 登录
+```
+
+### 3.3.1 常用选项
+
+- **-c<备注>**:修改用户帐号的备注文字。
+- **-a**:追加,默认的修改是覆盖
+- **-d登入目录>**:修改用户登入时的目录。
+- **-e<有效期限>**:修改帐号的有效期限。
+- **-f<缓冲天数>**:修改在密码过期后多少天即关闭该帐号。
+- **-g<群组>**:修改用户所属的群组。
+- **-G<群组>**:修改用户所属的附加群组。
+- **-l<帐号名称>**:修改用户帐号名称。
+- **-L**:锁定用户密码,使密码无效。
+- **-s**:修改用户登入后所使用的shell。
+- **-u**:修改用户ID。
+- **-U**:解除密码锁定。
+
+### 3.3.2 案例演示
+
+* 更改登录的目录
+
+```shell
+[root@localhost ~]# usermod -d /home user01
+[root@localhost ~]# su - user01
+[user01@localhost ~]$ pwd
+/home
+```
+
+* 改变用户的uid
+
+```shell
+[root@localhost ~]# usermod -u 6666 user02
+```
+
+## 3.4 删除用户:userdel
+
+userdel命令用于删除用户帐号
+
+userdel可删除用户帐号与相关的文件。若不加参数,则仅删除用户帐号,而不删除相关文件
+
+```shell
+userdel [-r][用户帐号]
+```
+
+### 3.4.1 常用选项
+
+- **-r**:删除用户登入目录以及目录中所有文件
+
+### 3.4.2 案例演示
+
+删除用户账号
+
+```shell
+ [root@localhost ~]# userdel user04
+```
+
+删除用户账户和家目录
+
+```shell
+[root@localhost ~]# userdel -r user03
+```
+
+# 4. passwd 文件中的 shell
+
+查看`/etc/passwd`文件会发现在每行的最后是登录成功之后执行的命令,有两种是使用最为频繁的:
+
+- /bin/bash:这个是 Linux 的命令行工具,我们正常登陆之后默认就是进入命令行
+- /sbin/nologin:如果写成 nologin,那么用户将无法登录,有些用户是作为进程权限管理而存在的,不需要登录。如果提供登录的功能反而不安全,所以写成 nologin
+
+```shell
+[root@localhost ~]# cat /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+bin:x:1:1:bin:/bin:/sbin/nologin
+daemon:x:2:2:daemon:/sbin:/sbin/nologin
+adm:x:3:4:adm:/var/adm:/sbin/nologin
+lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
+```
+
+我们可以新建一个用户,然后尝试自定义登录成功之后执行的命令,用来加深印象。
+
+```shell
+[root@localhost ~]# useradd test01
+[root@localhost ~]# tail -n 1 /etc/passwd
+test01:x:1000:1000::/home/test01:/bin/vi
+```
+
+切换到test01用户,会发现自动进入vi的界面,说明最后的这个段内容就是用户登录之后会运行的程序
+
+
+
+# 5. 用户密码管理
+
+root用户可以直接设置普通用户密码,普通用户必须要提供原密码,才可以修改自己密码。
+
+## 5.1 passwd
+
+passwd命令用来更改使用者的密码
+
+```shell
+passwd [选项...] <帐号名称>
+```
+
+### 5.1.1 常用选项
+
+- **-k**:保持身份验证令牌不过期
+- **-d**:删除已命名帐号的密码(只有根用户才能进行此操作)
+- **-l**:锁定指名帐户的密码(仅限 root 用户)
+- **-u**:解锁指名账户的密码(仅限 root 用户)
+- **-x**:密码的最长有效时限(只有根用户才能进行此操作)
+- **-n**:密码的最短有效时限(只有根用户才能进行此操作)
+- **-w**:在密码过期前多少天开始提醒用户(只有根用户才能进行此操作)
+- **-i**:当密码过期后经过多少天该帐号会被禁用(只有根用户才能进行此操作)
+- **-S**:报告已命名帐号的密码状态(只有根用户才能进行此操作)
+- **--stdin**:从标准输入读取令牌(只有根用户才能进行此操作)
+
+### 5.1.2 案例演示
+
+修改test01用户密码
+
+```shell
+[root@localhost ~]# passwd test01
+更改用户 test01 的密码 。
+新的 密码:
+重新输入新的 密码:
+passwd:所有的身份验证令牌已经成功更新。
+```
+
+使用管道符设置用户密码
+
+```shell
+[root@localhost ~]# echo 123456 | passwd --stdin test01
+更改用户 test01 的密码 。
+passwd:所有的身份验证令牌已经成功更新。
+```
+
+## 5.2 login.defs文件
+
+`/etc/login.defs`文件是用来创建用户时进行一定的限制,但是优先级低于`/etc/passwd`和`/etc/shadow`,如果有冲突的地方,系统会以`/etc/passwd`和`/etc/shadow`为准
+
+下面是这个文件的内容,egrep命令我们后续会讲到,这边可以理解为不看文件的注释和空行。
+
+```shell
+[root@localhost ~]# egrep -v '^[ ]*$|^#' /etc/login.defs
+MAIL_DIR /var/spool/mail # 系统消息(邮件)文件夹
+PASS_MAX_DAYS 99999 # 密码有效最大天数
+PASS_MIN_DAYS 0 # 密码有效最小天数
+PASS_MIN_LEN 5 # 密码长度
+PASS_WARN_AGE 7 # 密码失效警告倒计时
+UID_MIN 1000 # 用户UID最小1000
+UID_MAX 60000 # 用户UID最大60000
+SYS_UID_MIN 201 # 系统用户UID最小201
+SYS_UID_MAX 999 # 系统用户UID最大999
+GID_MIN 1000 # 用户组GID最小1000
+GID_MAX 60000 # 用户组GID最大60000
+SYS_GID_MIN 201
+SYS_GID_MAX 999
+CREATE_HOME yes # 创建家目录
+UMASK 077 # 创建文件/目录的权限掩码
+USERGROUPS_ENAB yes # 创建用户时同时生成组是 如果此处是no 创建的用户 会是gid=100(users)groups=100(users)
+ENCRYPT_METHOD SHA512 # 加密 方法 sha 512 这个方法生成的密码在/etc/shadow里面的第二列会以$6$开头
+```
+
+## 5.3 chage
+
+chage是用于更改用户密码过期信息
+
+```shell
+chage [选项] 登录
+```
+
+### 5.3.1 常用选项
+
+- **-d**:设置密码的最后更改日期
+- **-E 过期日期**:设置账号的过期日期
+- **-I INACITVE**:设置密码过期后若未更改,多少天后用户账号被禁用。
+- **-l**:显示用户账号的密码过期信息。
+- **-m 最小天数**:设置两次改变密码之间相距的最小天数
+- **-M 最大天数**:设置将两次改变密码之间相距的最大天数
+- **-W 警告天数**:设置密码过期前的警告天数
+
+### 5.3.2 案例演示
+
+强制用户在下次登录的时候换密码
+
+```shell
+[root@localhost ~]# chage -d 0 test01
+[root@localhost ~]# logout
+You must change your password now and login again!
+更改用户 test01 的密码 。
+为 test01 更改 STRESS 密码。
+(当前)UNIX 密码:
+
+[root@localhost ~]# chage -l root
+最近一次密码修改时间 :从不
+密码过期时间 :从不
+密码失效时间 :从不
+帐户过期时间 :从不
+两次改变密码之间相距的最小天数 :0
+两次改变密码之间相距的最大天数 :99999
+在密码过期之前警告的天数 :7
+
+# 设置用户 user01 的密码过期前7天提醒用户修改密码
+[root@localhost ~]# chage -W 7 user01
+
+# 设置用户 user01 的密码最短使用天数为7天,即密码修改后7天内不能再次修改
+[root@localhost ~]# chage -m 7 user01
+[root@localhost ~]# chage -l user01
+最近一次密码修改时间 :11月 08, 2024
+密码过期时间 :从不
+密码失效时间 :从不
+帐户过期时间 :从不
+两次改变密码之间相距的最小天数 :7
+两次改变密码之间相距的最大天数 :99999
+在密码过期之前警告的天数 :7
+```
+
+**小知识:** 当你新建用户的时候,用户的home目录下会有一些默认的隐藏文件,这些隐藏文件是在创建用户的时候从`/etc/skel/`中复制过去的。
+
+# 6. sudoers
+
+Linux是多用户多任务的操作系统, 共享该系统的用户往往不只一个。出于安全性考虑, 有必要通过useradd创建一些非root用户, 只让它们拥有不完全的权限; 如有必要,再来提升权限执行。
+
+sudo就是来解决这个需求的: 这些非root用户不需要知道root的密码,就可以提权到root,执行一些root才能执行的命令。
+
+```shell
+sudo [选项] [用户名] [命令]
+```
+
+## 6.1 sudo 命令执行过程
+
+1. 当用户执行sudo时,系统会主动寻找`/etc/sudoers`文件,判断该用户是否有执行sudo的权限
+2. 确认用户具有可执行sudo的权限后,让用户输入用户自己的密码确认
+3. 若密码输入成功,则开始执行sudo后续的命令
+
+## 6.2 赋予用户 sudo 操作的权限
+
+通过useradd添加的用户,并不具备sudo权限。在ubuntu/centos/RockyLinux等系统下, 需要将用户加入admin组或者wheel组或者sudo组。以root用户身份执行如下命令, 将用户加入wheel/admin/sudo组。
+
+```shell
+usermod -a -G wheel <用户名>
+```
+
+如果提示wheel组不存在, 则还需要先创建该组
+
+```shell
+groupadd wheel
+```
+
+## 6.3 配置文件
+
+sudo 的权限控制可以在 `/etc/sudoers` 文件中查看到。一般来说,通过 `cat /etc/sudoers` 指令来查看该文件, 会看到如下几行代码。
+
+```shell
+[root@localhost ~]# egrep -v '^[ ]*$|^#' /etc/sudoers
+=====省略=====
+root ALL=(ALL) ALL
+%wheel ALL=(ALL) ALL
+```
+
+对/etc/sudoers文件进行编辑的代码公式可以概括为
+
+```shell
+授权用户/组 主机=[(切换到哪些用户或组)] [是否需要输入密码验证] 命令1,命令2,...
+字段1 字段2 =[(字段3)] [字段4] 字段5
+```
+
+凡是[ ]中的内容, 都能省略; 命令和命令之间用`,`号分隔,字段3、字段4,是可以省略的。
+
+* "字段1"不以%号开头的表示"将要授权的用户",以%号开头的表示"将要授权的组"。
+* "字段2"表示允许登录的主机, ALL表示所有,;如果该字段不为ALL,表示授权用户只能在某些机器上登录本服务器来执行sudo命令
+* "字段3"如果省略, 相当于(root:root),表示可以通过sudo提权到root,如果为(ALL)或者(ALL:ALL), 表示能够提权到(任意用户:任意用户组)。
+* "字段4"的可能取值是NOPASSWD:。请注意NOPASSWD后面带有冒号:。表示执行sudo时可以不需要输入密码。
+ * 比如:`lucy ALL=(ALL) NOPASSWD: /bin/useradd`表示: 普通用户lucy可以在任何主机上, 通过sudo执行/bin/useradd命令, 并且不需要输入密码
+ * 比如:`peter ALL=(ALL) NOPASSWD: ALL`,表示: 普通用户peter可以在任何主机上, 通过sudo执行任何命令, 并且不需要输入密码。
+* "字段5"是使用逗号分开一系列命令,这些命令就是授权给用户的操作; ALL表示允许所有操作。命令都是使用绝对路径, 这是为了避免目录下有同名命令被执行,从而造成安全隐患。
+ * 如果你将授权写成如下安全性欠妥的格式:`lucy ALL=(ALL) chown,chmod,useradd`那么用户就有可能创建一个他自己的程序, 也命名为userad, 然后放在它的本地路径中, 如此一来他就能够使用root来执行这个"名为useradd的程序"。这是相当危险的!
+
+## 6.4 编辑配置文件
+
+在实践中,去编辑`/etc/sudoers`文件,系统提示我没权限,这是因为`/etc/sudoers`的内容如此敏感,以至于该文件是只读的。所以,编辑该文件前,请确认清楚你知道自己正在做什么。
+
+强烈建议通过`visudo`命令来修改该文件,通过`visudo`修改,如果配置出错,会有提示。
+
+官方文档推荐的做法,不是直接修改`/etc/sudoers`文件,而是将修改写在`/etc/sudoers.d/`目录下的文件中。如果使用这种方式修改sudoers,需要在`/etc/sudoers`文件的最后行,加上`#includedir /etc/sudoers.d`一行(默认已有)。需要注意,这个`#includedir /etc/sudoers.d`中的`#`并不是注释,请勿修改。
+
+## 6.5 sudo 选项
+
+* **-u**:以指定用户或 ID 运行命令(或编辑文件)
+* **-l**:显示出自己(执行 sudo 的使用者)的权限
+* **-b**:将要执行的指令放在后台执行
+* **-i**: 以目标用户身份运行一个登录 shell;可同时指定一条命令。相当于切换到root,不过只需要用户自己的密码即可。
+
+## 6.6 案例演示
+
+* 以管理员身份查看shadow文件
+
+```shell
+[root@localhost ~]# useradd user
+[root@localhost ~]# echo 123456 | passwd --stdin user
+[root@localhost ~]# usermod -a -G wheel user
+[root@localhost ~]# su - user
+[user@localhost ~]$ cat /etc/shadow
+cat: /etc/shadow: 权限不够
+[user@localhost ~]$ sudo -u root cat /etc/shadow
+[sudo] user 的密码:
+[user@localhost ~]$ sudo cat /etc/shadow
+# sudo -u root用的比较多,可以被精简为sudo
+```
+
+* 查看下列示例
+
+```shell
+papi ALL=(root) NOPASSWD: /bin/chown,/usr/sbin/useradd
+```
+
+* 表示: 用户papi能在所有可能出现的主机上, 提权到root下执行`/bin/chown`, 不必输入密码; 但运行`/usr/sbin/useradd`命令时需要密码
+* 在具有sudo操作的用户下, 执行`sudo -l`可以查看到该用户被允许和被禁止运行的命令
+
+* 查看下列示例
+
+```shell
+papi ALL=/usr/sbin/,/sbin/,!/usr/sbin/fdisk
+```
+
+* 命令前面加上!号表示取消该命令
+* 用户papi在所有可能出现的主机上, 能够运行目录/usr/sbin和/sbin下所有的程序, 但fdisk除外。
+
+* 默认情况下输入一次sudo可以保持15分钟不再要求输入密码,如果想要延长这个时间,可以修改配置文件
+
+```shell
+[root@localhost ~]# visudo
+Defaults env_reset,pwfeedback,timestamp_timeout=60
+# 这个是改成60分钟才会需要再次输入密码,并且输入密码的时候会显示*号
+```
+
diff --git a/01.Linux基础/06.用户权限管理/文件属性介绍.png b/01.Linux基础/06.用户权限管理/文件属性介绍.png
new file mode 100644
index 0000000..405108e
Binary files /dev/null and b/01.Linux基础/06.用户权限管理/文件属性介绍.png differ
diff --git a/01.Linux基础/06.用户权限管理/用户创建实战示例1.png b/01.Linux基础/06.用户权限管理/用户创建实战示例1.png
new file mode 100644
index 0000000..0fc55ed
Binary files /dev/null and b/01.Linux基础/06.用户权限管理/用户创建实战示例1.png differ
diff --git a/01.Linux基础/06.用户权限管理/用户创建实战示例2.png b/01.Linux基础/06.用户权限管理/用户创建实战示例2.png
new file mode 100644
index 0000000..a478e2a
Binary files /dev/null and b/01.Linux基础/06.用户权限管理/用户创建实战示例2.png differ
diff --git a/01.Linux基础/07.文件权限管理.md b/01.Linux基础/07.文件权限管理.md
new file mode 100644
index 0000000..f311009
--- /dev/null
+++ b/01.Linux基础/07.文件权限管理.md
@@ -0,0 +1,543 @@
+# 1. 文件权限
+
+文件权限设置:可以赋予某个用户或组,能够以何种方式,访问某个文件
+
+Linux 系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。
+
+为了保护系统的安全性,Linux 系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。
+
+在 Linux 中我们通常使用以下两个命令来修改文件或目录的所属用户与权限:
+
+* chown (change ownerp) : 修改所属用户与组。
+* chmod (change mode) : 修改用户的权限。
+
+在 Linux 中我们可以使用 ll 或者 ls –l 命令来显示一个文件的属性以及文件所属的用户和组
+
+
+
+每个文件的属性由左边第一部分的 10 个字符来确定(如下图)。
+
+
+
+从左至右用 0-9 这些数字来表示。
+
+* 第 0 位确定文件类型,第 1-3 位确定属主(该文件的所有者)拥有该文件的权限。
+* 第4-6位确定属组(所有者的同组用户)拥有该文件的权限,第7-9位确定其他用户拥有该文件的权限。
+* 其中,第 1、4、7 位表示读权限,如果用`r`字符表示,则有读权限,如果用`-`字符表示,则没有读权限;
+* 第 2、5、8 位表示写权限,如果用`w`字符表示,则有写权限,如果用`-`字符表示没有写权限;第 3、6、9 位表示可执行权限,如果用`x`字符表示,则有执行权限,如果用`-`字符表示,则没有执行权限。
+
+# 2. 修改文件属主chown
+
+chown用于设置文件所有者和文件关联组的命令
+
+chown 需要超级用户`root`的权限才能执行此命令
+
+```shell
+chown [选项]... [所有者][:[组]] 文件...
+```
+
+## 2.1 选项
+
+* **-R**: 处理指定目录以及其子目录下的所有文件
+* **-v**: 显示详细的处理信息
+
+## 2.2 实例
+
+* 设置所有者为root
+
+```shell
+[root@localhost ~]# chown root anaconda-ks.cfg
+```
+
+* 将文件的拥有者设置为user01,允许使用的组设置为it
+
+```shell
+[root@localhost ~]# chown user01:it file.txt
+```
+
+* 将目录下的所有文件拥有者设置为user01,允许使用的组设置为it
+
+```shell
+[root@localhost ~]# chown -R user01:it dir/*
+```
+
+# 3. 修改文件权限chmod
+
+chmod是控制用户对文件的权限的命令
+
+```shell
+chmod [选项]... 模式[,模式]... 文件...
+```
+
+## 3.1 模式
+
+mode : 权限设定字串,格式如下 :
+
+```shell
+[ugoa...][[+-=][rwx]...][,...]
+```
+
+* `u`表示该文件的拥有者,`g`表示与该文件的拥有者属于同一个群体(group)者,`o`表示其他以外的人,`a`表示这三者皆是。
+* `+`表示增加权限、`-`表示取消权限、`=`表示唯一设定权限。
+* `r`表示可读取,`w`表示可写入,`x`表示可执行
+* `r``w``x`权限对文件和目录的意义
+
+| 权限 | 对文件的影响 | 对目录的影响 |
+| :-------- | :------------------- | :--------------------------------------------------------- |
+| r(读取) | 可以读取文件的内容 | 可以列出目录的内容(文件名),可以使用ls命令 |
+| w(写入) | 可以更改文件的内容 | 可以创建或删除目录中的任一文件,可以使用touch、rm命令 |
+| x(可执行) | 可以作为命令执行文件 | 可以访问目录的内容(取决于目录中文件的权限),可以使用cd命令 |
+
+## 3.2 八进制语法
+
+chmod命令可以使用八进制数来指定权限。文件或目录的权限位是由9个权限位来控制,每三位为一组,它们分别是文件所有者(User)的读、写、执行,用户组(Group)的读、写、执行以及其它用户(Other)的读、写、执行。历史上,文件权限被放在一个比特掩码中,掩码中指定的比特位设为1,用来说明一个类具有相应的优先级。
+
+| # | 权限 | rwx | 二进制 |
+| :--- | :------------- | :--- | :----- |
+| 7 | 读 + 写 + 执行 | rwx | 111 |
+| 6 | 读 + 写 | rw- | 110 |
+| 5 | 读 + 执行 | r-x | 101 |
+| 4 | 只读 | r-- | 100 |
+| 3 | 写 + 执行 | -wx | 011 |
+| 2 | 只写 | -w- | 010 |
+| 1 | 只执行 | --x | 001 |
+| 0 | 无 | --- | 000 |
+
+例如, 765 将这样解释:
+
+* 所有者的权限用数字表达:属主的那三个权限位的数字加起来的总和。如 rwx ,也就是 4+2+1 ,应该是 7。
+* 用户组的权限用数字表达:属组的那个权限位数字的相加的总和。如 rw- ,也就是 4+2+0 ,应该是 6。
+* 其它用户的权限数字表达:其它用户权限位的数字相加的总和。如 r-x ,也就是 4+0+1 ,应该是 5。
+
+## 3.3 选项
+
+* **-f**: 若该文件权限无法被更改也不要显示错误讯息
+* **-v**: 显示权限变更的详细资料
+* **-R**: 对目前目录下的所有文件与子目录进行相同的权限变更(即以递归的方式逐个变更)
+
+## 3.4 实例
+
+* 限制用户user1对`file`文件的写入
+
+```shell
+[root@localhost ~]# chmod a-w /home/user1/file
+[root@localhost ~]# ls -lh /home/user1/file
+-r--r--r--. 1 user1 user1 0 4月 13 10:56 /home/user1/file
+[root@localhost ~]# su - user1
+上一次登录:二 4月 13 10:47:41 CST 2021pts/1 上
+[user1@localhost ~]$ echo "hello world" >> file
+-bash: file: 权限不够
+```
+
+* 限制所有用户删除dir目录下的文件
+
+```shell
+[root@localhost ~]# chmod a-w /home/user1/dir/
+[root@localhost ~]# ls -lhd /home/user1/dir
+dr-xr-xr-x. 2 user1 user1 18 4月 13 10:58 /home/user1/dir
+[root@localhost ~]# su - user1
+上一次登录:二 4月 13 10:57:11 CST 2021pts/1 上
+[user1@localhost ~]$ cd dir/
+[user1@localhost dir]$ rm -rf test
+rm: 无法删除"test": 权限不够
+```
+
+# 4. 文件访问控制列表
+
+文件访问控制列表(Access Control Lists,ACL)是Linux开的一套新的文件系统权限管理方法。
+
+传统的Linux文件系统的权限控制是通过user、group、other与r(读)、w(写)、x(执行)的不同组合来实现的。随着应用的发展,这些权限组合已不能适应现时复杂的文件系统权限控制要求。例如,我们可能需把一个文件的读权限和写权限分别赋予两个不同的用户或一个用户和一个组这样的组合。传统的权限管理设置起来就力不从心了。
+
+文件访问控制列表可以针对文件单独设置某个用户或者用户组队文件的管理权限。
+
+## 4.1 getfacl命名
+
+获取文件访问控制列表的详细内容
+
+```shell
+getfacl [-aceEsRLPtpndvh] file ...
+```
+
+### 4.1.1 选项
+
+* **-a**:仅显示文件访问控制列表
+* **-d**:仅显示默认的访问控制列表
+* **-c**:不显示注释表头
+* **-e**:显示所有的有效权限
+* **-E**:显示无效权限
+* **-R**:递归显示子目录
+* **-t**:使用制表符分隔的输出格式
+
+### 4.1.2 实例
+
+* 查看acl权限列表
+
+```shell
+[root@localhost ~]# getfacl anaconda-ks.cfg
+# file: anaconda-ks.cfg
+# owner: root
+# group: root
+user::rwx
+group::r-x
+other::r-x
+```
+
+* 查看acl权限列表,不显示注释表头
+
+```shell
+[root@localhost ~]# getfacl -c anaconda-ks.cfg
+user::rwx
+group::r-x
+other::r-x
+```
+
+## 4.2 setfacl命令
+
+用来设置更精确的文件权限
+
+```shell
+setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
+```
+
+### 4.2.1 选项
+
+* **-m**:更改文件的访问控制列表
+* **-M**:从文件读取访问控制列表条目更改
+* **-x**:根据文件中访问控制列表移除条目
+* **-X**:从文件读取访问控制列表条目并删除
+* **-b**:删除所有扩展访问控制列表条目
+* **-k**:移除默认访问控制列表
+* **-d**:应用到默认访问控制列表的操作
+* **-R**:递归操作子目录
+
+### 4.2.2 实例
+
+* 给指定用户添加acl权限
+* 首先用户user1是没有`/workdir`的权限的
+
+```shell
+[root@localhost ~]# groupadd worker
+[root@localhost ~]# mkdir /workdir
+[root@localhost ~]# chown root:worker /workdir
+[root@localhost ~]# chmod 770 /workdir # 不允许其他用户对目录的权限
+[root@localhost ~]# ll -d /workdir/
+drwxrwx---. 2 root worker 6 4月 14 09:14 /workdir/
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ cd /workdir/
+-bash: cd: /workdir/: 权限不够
+```
+
+* 单独给予user1的可读和可进入权限
+
+```shell
+[root@localhost ~]# setfacl -m u:user1:rx /workdir/
+[root@localhost ~]# getfacl -c /workdir
+user::rwx
+user:user1:r-x # 成功添加user1对workdir的权限
+group::rwx
+mask::rwx
+other::---
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ cd /workdir/
+[user1@localhost workdir]$ ll -d
+drwxrwx---+ 2 root worker 6 4月 14 09:14 . # 权限位后面多了一个"+",表示存在ACL权限
+[user1@localhost workdir]$ touch file
+touch: 无法创建"file": 权限不够
+```
+
+* 移除user1的访问控制列表权限
+
+```shell
+[root@localhost ~]# setfacl -x u:user1 /workdir/
+[root@localhost ~]# getfacl -c /workdir/
+user::rwx
+group::rwx
+mask::rwx
+other::---
+```
+
+* 创建worker2组,然后给这个组访问acl的权限,将user1加入worker2组验证是否成功
+
+```shell
+[root@localhost ~]# groupadd worker2
+[root@localhost ~]# setfacl -m g:worker2:rwx /workdir
+[root@localhost ~]# usermod -aG worker2 user1
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ cd /workdir/
+[user1@localhost workdir]$ touch file
+```
+
+* 对workdir设置的acl权限并不会被之后在workdir下创建的子文件和子目录继承,可以设置默认ACL权限,来让目录下面的新建文件和文件夹都继承父目录的权限
+
+```shell
+[root@localhost ~]# setfacl -b /workdir
+[root@localhost ~]# setfacl -m d:u:user1:rx /workdir
+# 在前面加上一个d,就可以设置默认facl权限
+[root@localhost ~]# getfacl -c /workdir
+user::rwx
+group::rwx
+other::---
+default:user::rwx # 前面多出来了default
+default:user:user1:r-x
+default:group::rwx
+default:mask::rwx
+default:other::---
+[root@localhost ~]# touch /workdir/newfile
+[root@localhost ~]# getfacl -c /workdir/newfile
+user::rw-
+user:user1:r-x #effective:r-- # 新建的文件会自动继承
+group::rwx #effective:rw-
+mask::rw-
+other::---
+```
+
+# 5. mask有效权限
+
+mask 权限,指的是用户或群组能拥有的最大 ACL 权限,也就是说,给用户或群组设定的 ACL 权限不能超过 mask 规定的权限范围,超出部分做无效处理。
+
+注意上面的案例,在newfile的facl中,有一个mask权限是`rw-`,所以我们即使给了user1`r-x`权限,在实际生效的时候,`x`也不会有的,注意后面的提示`#effective:r--`表示`x`权限并没有赋予。
+
+## 5.1 实例
+
+* 修改上面案例中的newfile的mask权限
+
+```shell
+[root@localhost ~]# setfacl -m m::rwx /workdir/newfile
+[root@localhost ~]# getfacl -c /workdir/newfile
+user::rw-
+user:user1:r-x
+group::rwx
+mask::rwx
+other::---
+```
+
+# 6. 特殊权限
+
+文件除了上述的`r`,`w`,`x`权限以外,还有三个特殊权限:suid,sgid,sticky
+
+## 6.1 suid
+
+suid 属性只能运用在可执行文件上,含义是开放文件所有者的权限给其他用户,即当用户执行该执行文件时,会拥有该执行文件所有者的权限。如果给一个非二进制文件文件附加suid权限,则会显示大写S,属于无效。
+
+普通用户能够执行`passwd`命令修改自己的密码,修改密码其实就是修改`/etc/shadow`这个文件,查看`/etc/passwd`这个文件的权限,发现除了`root`其他人没有写权限,但是普通用户能够成功执行`passwd`,其原因就在于`passwd`这个命令的权限是`-rwsr-xr-x`,其中`s`的作用就是让执行命令的人具有和该命令拥有者相同的权限。
+
+```shell
+[root@localhost ~]# ll /usr/bin/passwd
+-rwsr-xr-x. 1 root root 32656 May 15 2022 /usr/bin/passwd
+```
+
+### 6.1.1 实例
+
+* 切换成普通用户输入修改密码命令
+
+```shell
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ passwd
+更改用户 user1 的密码 。
+为 user1 更改 STRESS 密码。
+(当前)UNIX 密码:
+```
+
+* 保持这个会话别端口,新建一个ssh会话,查看系统进程,可以看到当前是调用root用户执行的passwd命令
+
+```shell
+[root@localhost ~]# ps -aux |grep passwd
+root 2031 0.0 0.3 14904 6656 pts/2 S+ 22:30 0:00 passwd
+root 2034 0.0 0.1 3876 2048 pts/1 S+ 22:31 0:00 grep --color=auto passwd
+```
+
+* 如果想某个文件添加suid权限,可以输入下面两个命令
+
+```shell
+chmod u+s file
+chmod 4765 file
+```
+
+要设置特殊权限,可以使用`chmod`命令的4位数字表示法,其中第一位用于特殊权限,后三位分别代表所有者、组和其他用户的权限。特殊权限的设置如下:
+
+\- `4`: 设置setuid。
+\- `2`: 设置setgid。
+\- `1`: 设置sticky bit。
+
+以下是一些设置特殊权限的例子:
+
+\- 设置setuid: `chmod u+s file`
+\- 设置setgid: `chmod g+s file`
+\- 设置sticky bit: `chmod o+t /dir`
+
+如果你想要将特殊权限与其他权限组合使用,可以这样:
+
+\- 设置文件的setuid和可读可执行权限:`chmod 4555 file`
+\- 设置目录的setgid和可读可执行可进入权限:`chmod 2775 /dir`
+
+请注意,特殊权限的设置需要谨慎,因为它们可能会影响系统的安全性和文件的访问控制。通常,只有系统管理员或有经验的用户才会设置这些权限。
+
+## 6.2 sgid
+
+sgid 属性可运用于二进制文件或者目录,运用在文件的含义是开放文件所属组的权限给其他用户,即当用户执行该执行文件时,会拥有该执行文件所属组用户的权限。如果给一个非二进制文件文件附加sgid权限,则会显示大写S,属于无效。
+
+运用在目录上的含义是,在该目录下所有用户创建的文件或者目录的所属组都和其一样。即如果`/home/user1`目录具有sgid权限,且所属组是`user1`,则任何用户在`/home/user1`下创建的子目录或者文件的所属组都是`user1`。
+
+### 6.2.1 实例
+
+* 设置sgid,让用户在workdir下创建的文件都属于worker组
+
+```shell
+[root@localhost ~]# mkdir /workdir
+[root@localhost ~]# groupadd worker
+[root@localhost ~]# chown .worker /workdir/
+[root@localhost ~]# ll -d /workdir/
+drwxr-xr-x. 2 root worker 6 Nov 15 22:42 /workdir/
+[root@localhost ~]# chmod g+s /workdir/
+[root@localhost ~]# cd /workdir/
+[root@localhost workdir]# touch file
+[root@localhost workdir]# ll
+total 0
+-rw-r--r--. 1 root worker 0 Nov 15 22:44 file
+```
+
+## 6.3 sticky
+
+sticky 权限只能运用于目录上,含义是该目录下所有的文件和子目录只能由所属者删除,即使其的权限是777或者其他。一个公共目录,每个人都可以创建文件,删除自己的文件,但不能删除别人的文件(仅对目录有效)。
+
+### 6.3.1 实例
+
+* 设置sticky,让普通用户只能创建文件,不能删除文件
+
+```shell
+[root@localhost ~]# mkdir /workdir
+[root@localhost ~]# chmod 1777 /workdir/
+[root@localhost ~]# ll -d /workdir/
+drwxrwxrwt. 2 root root 6 Nov 15 22:47 /workdir/
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ cd /workdir/
+[user1@localhost workdir]$ touch user1file
+[user1@localhost workdir]$ exit
+logout
+[root@localhost ~]# useradd user2
+[root@localhost ~]# su - user2
+[user2@localhost ~]$ cd /workdir/
+[user2@localhost workdir]$ rm -rf user1file # 不能删除别人的创建的文件
+rm: cannot remove 'user1file': Operation not permitted
+[user2@localhost workdir]$ touch user2file
+[user2@localhost workdir]$ rm -rf user2file # 只能删除自己创建的文件
+[user2@localhost workdir]$ ll
+total 0
+-rw-r--r--. 1 user1 user1 0 Nov 15 22:48 user1file
+```
+
+# 7. chattr文件属性
+
+chattr命令用于改变文件属性。
+
+这项指令可改变存放在文件或目录属性,这些属性共有以下8种模式:
+
+* **a**:让文件或目录仅供追加用途
+* **b**:不更新文件或目录的最后存取时间
+* **c**:将文件或目录压缩后存放
+* **i**:不得任意更动文件或目录
+* **s**:保密性删除文件或目录
+* **S**:即时更新文件或目录
+* **u**:预防意外删除
+
+```shell
+chattr [-RV][+/-/=<属性>][文件或目录...]
+```
+
+## 7.1 选项
+
+* **-R**:递归处理,将指定目录下的所有文件及子目录一并处理
+* **-v <版本编号>**:设置文件或目录版本
+* **-V**:显示指令执行过程
+* **+ <属性>**:开启文件或目录的该项属性
+* **- <属性>**:关闭文件或目录的该项属性
+* **= <属性>**:指定文件或目录的该项属性
+
+## 7.2 实例
+
+* 用chattr命令防止系统中某个关键文件被修改
+
+```shell
+[root@localhost ~]# chattr +i /etc/resolv.conf
+[root@localhost ~]# lsattr /etc/resolv.conf
+----i----------- /etc/resolv.conf
+[root@localhost ~]# echo test >> /etc/resolv.conf
+-bash: /etc/resolv.conf: 权限不够
+```
+
+* 让某个文件只能往里面追加数据,但不能删除,适用于各种日志文件
+
+```shell
+[root@localhost ~]# chattr +a /var/log/messages
+[root@localhost ~]# lsattr /var/log/messages
+-----a---------- /var/log/messages
+[root@localhost ~]# echo > /var/log/messages # 不允许清空日志
+-bash: /var/log/messages: 不允许的操作
+```
+
+# 8. umask
+
+umask命令指定在建立文件时预设的权限掩码,进程、新建文件、目录的默认权限会收到umask的影响,umask表示要减掉得到权限。
+
+umask可用来设定[权限掩码]。[权限掩码]是由3个八进制的数字所组成,将现有的存取权限减掉权限掩码后,即可产生建立文件时预设的权限。
+
+```shell
+umask [选项][权限掩码]
+```
+
+## 8.1 选项
+
+* **-S**:以文字的方式来表示权限掩码
+
+## 8.2 实例
+
+* 查看当前用户的umask权限
+
+```shell
+[root@localhost ~]# umask
+0022
+```
+
+* 查看最终有的权限
+
+```shell
+[root@localhost ~]# umask -S
+u=rwx,g=rx,o=rx
+```
+
+* 修改umask的数值(临时)
+
+```shell
+[root@localhost ~]# umask 0000
+[root@localhost ~]# mkdir dir
+[root@localhost ~]# ll
+总用量 4
+drwxrwxrwx. 2 root root 6 4月 14 11:25 dir
+-rw-rw-rw-. 1 root root 0 4月 14 11:25 file
+```
+
+* 修改umask的数值(永久)
+
+```shell
+[root@localhost ~]# vim /etc/profile
+--------------
+ 59 if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
+ 60 umask 002
+ 61 else
+ 62 umask 022
+ 63 fi
+---------------
+[root@localhost ~]# source /etc/profile # 立即在当前shell中生效
+```
+
+* 通过umask决定新建用户`HOME`目录的权限
+
+```shell
+[root@localhost ~]# vim /etc/login.defs
+-----------------
+ 61 # The permission mask is initialized to this value. If not specified,
+ 62 # the permission mask will be initialized to 022.
+ 63 UMASK 077
+------------------
+```
+
diff --git a/01.Linux基础/07.文件权限管理/文件ugo权限解释.png b/01.Linux基础/07.文件权限管理/文件ugo权限解释.png
new file mode 100644
index 0000000..4b1c755
Binary files /dev/null and b/01.Linux基础/07.文件权限管理/文件ugo权限解释.png differ
diff --git a/01.Linux基础/07.文件权限管理/文件权限介绍.png b/01.Linux基础/07.文件权限管理/文件权限介绍.png
new file mode 100644
index 0000000..f8f5b8a
Binary files /dev/null and b/01.Linux基础/07.文件权限管理/文件权限介绍.png differ
diff --git a/01.Linux基础/08.进程管理.md b/01.Linux基础/08.进程管理.md
new file mode 100644
index 0000000..ff7b8d2
--- /dev/null
+++ b/01.Linux基础/08.进程管理.md
@@ -0,0 +1,680 @@
+# 1. 进程
+
+进程是一个在系统中运行的程序
+
+进程是已启动的可执行程序的运行实例,进程有以下组成部分
+
+* 已分配内存的地址空间
+* 安全属性,包括所有权凭据和特权
+* 进程代码的一个或多个执行线程
+* 进程状态
+
+程序:二进制文件,是静态的
+
+`/bin/date`,`/usr/sbin/httpd`,`/usr/sbin/sshd`,`/usr/local/nginx/sbin/ngix`
+
+进程:是程序运行的过程,动态的,有生命周期及运行状态
+
+# 2. 进程类型
+
+守护进程:在系统引导过程中启动的进程,跟终端无关的进程
+
+前台进程:跟终端相关,通过终端启动的进程
+
+# 3. 进程的生命周期
+
+
+
+父进程复制自己的地址空间(fork)创建一个新的(子)进程结构。每个新进程分配一个唯一的进程ID(PID),满足跟踪安全性之需。PID和父进程ID(PPID)是子进程环境的元素,任何进程都可以创建子进程,所有进程都是第一个系统进程的后代。
+
+# 4. systemd简介
+
+首先 systmed 是一个用户空间的程序,属于应用程序,不属于 Linux 内核范畴。Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 sysvinit(这个是centos6中的初始化系统)固有的缺点,提高系统的启动速度。
+
+Linux内核加载启动后,用户空间的第一个进程就是初始化进程,这个程序的物理文件约定位于`/sbin/init`,当然也可以通过传递内核参数来让内核启动指定的程序。这个进程的特点是进程号为1,代表第一个运行的用户空间进程。不同发行版采用了不同的启动程序,主要有以下几种主流选择:
+
+* 以 Ubuntu 为代表的 Linux 发行版采用 upstart
+* 红帽系列发行版本中
+ - 红帽6以前的版本使用System V init
+ - 红帽7及以后,使用systemd
+
+RockyLinux上所有的进程都是systemd的后代,systemd的功能繁多,不仅用来管理服务,还可以管理挂载点,定义定时任务等。这些工作都是由编辑相应的配置单元文件完成的。
+
+## 4.1 systemd unit 类型
+
+systemd需要管理的功能比较多,所以支持的配置单元类型也比较繁多,我们在日常使用Linux的过程中对系统服务的管理最多,所以我们主要了解一下`service`类型即可,其他类型作为一个了解,下面列举出所有类型详细的解释。
+
+| **单元类型** | **文件格式** | **描述** |
+| :------------- | :----------- | :----------------------------------------------------------- |
+| Service unit | .service | 服务类 |
+| Target unit | .target | 一个 unit 服务组,用于模拟实现运行级别 |
+| Automount unit | .automount | 文件系统自动挂载点 |
+| Device unit | .device | 内核识别的设备文件 |
+| Mount unit | .mount | 文件系统挂载点 |
+| Path unit | .path | 文件或目录 |
+| Scope unit | .scope | 外部创建的进程 |
+| Slice unit | .slice | A group of hierarchically organized units that manage system processes. |
+| Snapshot unit | .snapshot | 系统快照 |
+| Socket unit | .socket | 套接字 |
+| Swap unit | .swap | 标识 swap 设备 |
+| Timer unit | .timer | systemd 的计时器 |
+
+## 4.2 unit 文件保存位置
+
+我们目前了解到文件所在的位置即可,关于文件内部的格式与如何修改这些文件,我们会在后续的服务搭建过程中细讲。
+
+| **目录** | **描述** |
+| :----------------------- | :-------------------------------- |
+| /usr/lib/systemd/system/ | RPM 包安装时分发的 unit 文件 |
+| /run/systemd/system/ | systemd 运行时创建的文件 |
+| /etc/systemd/system/ | systemctl enable 创建的 unit 文件 |
+
+# 5. 管理系统服务
+
+systemd 的主要命令行工具是`systemctl`
+
+```shell
+systemctl [选项...] {命令} ...
+```
+
+## 5.1 systemctl常用命令
+
+这边列举出来的命令会在后面的学习过程中经常用到,所以大家只要对本部分中系统管理的命令合集有一个影响即可。
+
+| **命令** | **描述** |
+| :----------------------------------------------------------- | :------------------------------------- |
+| systemctl start name.service | 启动服务 |
+| systemctl stop name.service | 停止服务 |
+| systemctl restart name.service | 重启服务(没启动的服务会启动) |
+| systemctl try-restart name.service | 只重启正在运行的服务 |
+| systemctl reload name.service | 重载配置文件 |
+| systemctl status name.service systemctl is-active name.service | 检查服务状态检查服务是否启动 |
+| systemctl list-units --type service --all | 显示所有的服务状态 |
+| systemctl enable name.service | 启用开机自启服务 |
+| systemctl disable name.service | 停用自启服务 |
+| systemctl status name.service systemctl is-enabled name.service | 检查服务状态查看服务是否自启 |
+| systemctl list-unit-files --type service | 查看所有服务 |
+| systemctl list-dependencies --after | 列出在指定服务之前启动的服务(依赖) |
+| systemctl list-dependencies --before | 列出在指定服务之后启动的服务(被依赖) |
+
+# 6. ps
+
+ps命令用于显示当前进程的状态,类似于 windows 的任务管理器
+
+```shell
+ps [选项]
+```
+
+## 6.1 选项
+
+* **-a**:列出所有的进程
+* **-e**:列出所有的进程,等同于`-A`
+* **-f**:显示不包含资源使用率的相关信息
+* **‐H**:以进程层级格式显示进程相关信息
+* **-w**:显示加宽可以显示较多的信息
+* **-u**:显示较详细的信息
+* **-x**:显示其他使用者的进程
+
+显示信息的格式说明
+
+| **列名** | **说明** |
+| :------- | :----------------- |
+| USER | 进程拥有者 |
+| PID | 进程ID |
+| %CPU | 占用的 CPU 使用率 |
+| %MEM | 占用的内存使用率 |
+| VSZ | 占用的虚拟内存大小 |
+| RSS | 占用的常驻内存大小 |
+| TTY | 执行的终端编号 |
+| STAT | 该进程的状态* |
+| START | 进程开始时间 |
+| TIME | CPU使用时间 |
+| COMMAND | 所执行的命令 |
+
+*STAT表示的进程状态有如下几种:
+
+* **D**: 无法中断的休眠状态 ,将一直等待事件的发生或等待某种系统资源
+* **R**: 正在执行中
+* **S**: 可中断状态
+* **T**: 暂停执行
+* **Z**: 不存在但暂时无法消除,也叫僵尸进程
+ * 每个进程在运行结束后都会处于僵死状态,等待父进程调用进而释放系统资源,处于该状态的进程已经运行结束,但是它的父进程还没有释放其系统资源
+ * 孤儿进程:
+* **W**: 没有足够的内存可分配
+* **<**: 高优先序的进程
+* **N**: 低优先序的进程
+* **+**:前台进程
+* **l**:多线程进程
+* **s**:主进程(先导进程)
+
+## 6.2 实例
+
+**常用组合:ps aux**
+
+```bash
+u:以用户为中心组织进程状态信息显示
+a:与终端相关的进程;
+x:与终端无关的进程;
+[root@localhost ~]# ps aux | head -n 5
+USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+root 1 0.0 0.3 128144 6656 ? Ss 5月10 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
+root 2 0.0 0.0 0 0 ? S 5月10 0:00 [kthreadd]
+root 3 0.0 0.0 0 0 ? S 5月10 0:00 [ksoftirqd/0]
+root 5 0.0 0.0 0 0 ? S< 5月10 0:00 [kworker/0:0H]
+```
+
+**常用组合:ps -aux**
+
+```sh
+-a: 列出所有的进程
+-u: 显示较详细的信息
+-x: 显示其他使用者的进程
+[root@localhost ~]# ps -aux
+USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+root 1 0.1 0.9 172972 16128 ? Ss 20:38 0:01 /usr/lib/sys
+root 2 0.0 0.0 0 0 ? S 20:38 0:00 [kthreadd]
+root 3 0.0 0.0 0 0 ? I< 20:38 0:00 [rcu_gp]
+root 4 0.0 0.0 0 0 ? I< 20:38 0:00 [rcu_par_gp]
+root 5 0.0 0.0 0 0 ? I< 20:38 0:00 [slub_flushw
+root 6 0.0 0.0 0 0 ? I< 20:38 0:00 [netns]
+```
+
+**ps aux和ps -aux两个命令的区别:**
+
+`ps aux` 是一种 **BSD 风格** 的 `ps` 命令,它不需要破折号(`-`)作为选项的前缀。
+
+- **`a`**:显示所有用户的进程,包括其他用户的进程(不仅限于当前用户)。
+- **`u`**:以用户为中心的格式显示进程信息,提供更多详细信息,如用户名、CPU 和内存使用率等。
+- **`x`**:显示没有控制终端(TTY)的后台进程。
+
+`ps -aux` 与 `ps aux` 看起来很相似,但它们有不同的含义。
+
+- 这里的 `-` 表示使用的是 **UNIX 标准** 或 **POSIX 标准** 的 `ps` 选项。
+- 作为 POSIX 风格,`-a`、`-u`、`-x` 的含义会有所不同,甚至可能与 BSD 风格冲突。
+
+**常用组合:ps -ef**
+
+```bash
+-e:显示所有进程
+-f:显示完整格式程序信息
+[root@localhost ~]# ps -ef |head -n 10
+UID PID PPID C STIME TTY TIME CMD
+root 1 0 0 5月10 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
+root 2 0 0 5月10 ? 00:00:00 [kthreadd]
+root 3 2 0 5月10 ? 00:00:00 [ksoftirqd/0]
+root 5 2 0 5月10 ? 00:00:00 [kworker/0:0H]
+root 6 2 0 5月10 ? 00:00:00 [kworker/u256:0]
+root 7 2 0 5月10 ? 00:00:00 [migration/0]
+root 8 2 0 5月10 ? 00:00:00 [rcu_bh]
+root 9 2 0 5月10 ? 00:00:01 [rcu_sched]
+root 10 2 0 5月10 ? 00:00:00 [lru-add-drain]
+
+```
+
+**常用组合:ps -efH**
+
+```shell
+`查看进程以层级格式(类似于pstree命令)`
+[root@localhost ~]# ps -efH
+root 1 0 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
+root 479 1 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd-journald
+root 500 1 0 14:26 ? 00:00:00 /usr/sbin/lvmetad -f
+root 507 1 0 14:26 ? 00:00:00 /usr/lib/systemd/systemd-udevd
+root 615 1 0 14:27 ? 00:00:00 /sbin/auditd
+polkitd 638 1 0 14:27 ? 00:00:00 /usr/lib/polkit-1/polkitd --no-debug
+dbus 639 1 0 14:27 ? 00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
+root 646 1 0 14:27 ? 00:00:00 /usr/sbin/NetworkManager --no-daemon
+root 649 1 0 14:27 ? 00:00:00 /usr/sbin/irqbalance --foreground
+root 653 1 0 14:27 ? 00:00:00 /usr/lib/systemd/systemd-logind
+root 655 1 0 14:27 ? 00:00:00 /usr/sbin/crond -n
+chrony 661 1 0 14:27 ? 00:00:00 /usr/sbin/chronyd
+root 662 1 0 14:27 ? 00:00:00 login -- root
+```
+
+**按照CPU使用率排序查看所有进程**
+
+```shell
+[root@localhost ~]# ps -aux --sort %cpu # 递增
+[root@localhost ~]# ps -aux --sort -%cpu # 递减
+```
+
+**按照实际内存使用排序查看所有进程**
+
+```shell
+[root@localhost ~]# ps -aux --sort rss # 递增
+[root@localhost ~]# ps -aux --sort -rss # 递减
+```
+
+**按照父子进程显示ssh服务的层级关系**
+
+```shell
+[root@localhost ~]# ps -auxf |grep sshd
+# ps -efH
+root 6814 0.0 0.2 112756 4320 ? Ss 09:06 0:00 /usr/sbin/sshd -D
+root 7097 0.0 0.2 158760 5576 ? Ss 09:06 0:00 \_ sshd: root@pts/0
+root 7337 0.1 0.2 158760 5588 ? Ss 10:21 0:00 \_ sshd: root@pts/1
+root 7364 0.0 0.0 112724 988 pts/1 S+ 10:24 0:00 \_ grep --color=auto sshd
+```
+
+**自定义显示格式**
+
+```shell
+[root@localhost ~]# ps -axo user,pid,ppid,%mem,%cpu,command --sort -%cpu
+```
+
+**查看指定进程的PID,多种查看的方式**
+
+```shell
+[root@localhost ~]# cat /run/sshd.pid
+[root@localhost ~]# ps -aux |grep sshd
+[root@localhost ~]# pgrep -l sshd
+[root@localhost ~]# pidof sshd
+```
+
+**查看进程树**
+
+```shell
+[root@localhost ~]# yum install -y psmisc
+[root@localhost ~]# pstree
+systemd─┬─NetworkManager───2*[{NetworkManager}]
+ ├─agetty
+ ├─atd
+ ├─auditd─┬─sedispatch
+ │ └─2*[{auditd}]
+ ├─bluetoothd
+ ├─chronyd
+ ├─crond
+ ├─dbus-broker-lau───dbus-broker
+ ├─firewalld───{firewalld}
+ ├─irqbalance───{irqbalance}
+ ├─lsmd
+ ├─mcelog
+ ├─polkitd───7*[{polkitd}]
+ ├─rsyslogd───2*[{rsyslogd}]
+ ├─sshd───sshd───sshd───bash───bash───pstree
+ ├─systemd───(sd-pam)
+ ├─systemd-journal
+ ├─systemd-logind
+ ├─systemd-udevd
+ └─tuned───3*[{tuned}]
+```
+
+# 7. top
+
+top命令用于实时显示 process 的动态
+
+## 7.1 示例
+
+```shell
+[root@localhost ~]# top
+```
+
+第1行:系统时间、运行时间、登录终端数、系统负载(三个数值分别为1分钟、5分钟、15分钟内的平 均值,数值越小意味着负载越低)。
+
+第2行:进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数。
+
+第3行:用户占用资源百分比、系统内核占用资源百分比、改变过优先级的进程资源百分比、空闲的资源百分比等。
+
+第4行:物理内存总量、内存使用量、内存空闲量、作为内核缓存的内存量。(buffer和cache之间的区 别,cache是提高cpu和内存之间的数据交换速度,buffer是io设备和存储设备之间的缓冲区)
+
+第5行:虚拟内存总量、虚拟内存使用量、虚拟内存空闲量、已被提前加载的内存量。
+
+## 7.2 选项
+
+* **-d**: 改变显示的更新速度,或是在交互式指令列( interactive command)按 s
+* **-c**: 切换显示模式,共有两种模式,一是只显示程序的名称,另一种是显示完整的路径与名称
+* **-S**: 累积模式,会将己完成或消失的子行程 ( dead child process ) 的 CPU time 累积起来
+* **-s**: 安全模式,将交互式指令取消, 避免潜在的危机
+* **-i**: 不显示任何闲置 (idle) 或无用 (zombie) 的行程
+* **-n**: 更新的次数,完成后将会退出 top
+* **-b**: 显示模式,搭配 "n" 参数一起使用,可以用来将 top 的结果输出到文件内
+* **-z:**彩色
+
+## 7.3 交互模式快捷键
+
+| 快捷键 | 功能 |
+| :----- | :------------------------------------------------------- |
+| 空格 | 立即刷新 |
+| P | 根据CPU使用多少排序 |
+| T | 根据时间、累计排序 |
+| q | 退出top命令 |
+| m | 切换显示内存信息 |
+| t | 切换显示进程和CPU状态信息 |
+| c | 切换显示命令名称和完整命令行 |
+| M | 根据内存的大小排序 |
+| W | 将当前设置写入 ~/.toprc 文件中,这是top配置文件推荐方法 |
+| N | 以PID的大小排序 |
+| z | 彩色 |
+
+## 7.4 实例
+
+* 显示进程信息,每个1秒钟刷新一次
+
+```shell
+[root@localhost ~]# top -d 1
+```
+
+* 显示完整命令
+
+```shell
+[root@localhost ~]# top -c
+```
+
+* 更新两次后终止更新显示
+
+```shell
+[root@localhost ~]# top -n 2
+```
+
+* 显示指定的进程信息
+
+```shell
+[root@localhost ~]# top -p 7097
+```
+
+- 查看指定用户的进程
+
+```sh
+[root@localhost ~]# top -d 1 -u user01
+```
+
+- 将2次top信息写入到文件
+
+```sh
+[root@localhost ~]# top -d 1 -b -n 2 > top.txt
+```
+
+# 8. kill
+
+kill 命令用于删除执行中的程序或工作
+
+kill 可将指定的信号送至程序。预设的信号为 SIGTERM(15),可将指定程序终止
+
+```shell
+kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>][程序]
+```
+
+## 8.1 选项
+
+* **-l <信号编号>**: 若不加<信号编号>选项,则 -l 参数会列出全部的信号名称
+* **-s <信号名称或编号>**:指定要送出的信息
+* **[程序]**:[程序]可以是程序的PID或是PGID
+
+使用 kill -l 命令列出所有可用信号,最常用的信号如下
+
+| **编号** | **信号名** | **作用** |
+| :------- | :--------- | :------------------------------------------- |
+| 1 | SIGHUP | 重新加载配置 |
+| 2 | SIGINT | 通过键盘 `ctrl+c` 打印捕获信息,程序继续运行 |
+| 3 | SIGQUIT | 通过键盘 `ctrl+\` 打印捕获信息,程序优雅退出 |
+| 9 | SIGKILL | 强制终止 |
+| 15 | SIGTERM | 终止(正常结束) |
+| 18 | SIGCONT | 继续 |
+| 19 | SIGSTOP | 停止 |
+| 20 | SIGTSTP | 暂停`ctrl z` |
+
+## 8.2 实例
+
+* 杀死所有的ping命令,在linux命令中,使用反引号`包含的命令会优先执行,并将执行的结果作为参数提供给命令。
+
+```shell
+[root@localhost ~]# kill `pgrep ping`
+```
+
+* 强制杀死进程
+
+```shell
+[root@localhost ~]# kill -9 `pgrep ping`
+```
+
+* 温柔的杀死进程
+
+```bash
+[root@localhost ~]# kill -15 `pgrep ping`
+```
+
+# 9. pkill
+
+pkill 用于杀死一个进程,与 kill 不同的是它会杀死指定名字的所有进程
+
+```shell
+pkill [选项] name
+```
+
+## 9.1 选项
+
+* **name**: 进程名
+* **-u**:指定用户名
+* **-t**:指定终端
+
+## 9.2 实例
+
+* 结束所有的sshd进程
+
+```shell
+[root@localhost ~]# pkill sshd
+```
+
+* 结束用户user1的所有进程
+
+```shell
+[root@localhost ~]# pkill -u user1
+```
+
+* 终止pts/2上所有进程
+
+```shell
+[root@localhost ~]# pkill -t pts/2
+```
+
+* 终止pts/2上所有进程,并结束pts/2
+
+```shell
+[root@localhost ~]# pkill -9 -t pts/1
+```
+
+* 查看远程登录用户,并踢出用户
+
+```shell
+[root@localhost ~]# w
+ 15:02:26 up 5:21, 2 users, load average: 0.05, 0.03, 0.05
+USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
+root tty1 14:41 20:34 0.02s 0.02s -bash
+root pts/0 192.168.175.1 14:42 2.00s 0.05s 0.01s w
+user1 pts/1 192.168.175.1 14:40 20:34 0.02s 0.02s -bash
+[root@localhost ~]# pkill -u user1
+```
+
+# 10. 进程优先级 nice
+
+## 10.1 Linux进程调度及多任务
+
+每个CPU(或CPU核心)在一个时间点上只能处理一个进程,通过时间片技术,Linux实际能够运行的进程 (和线程数)可以超出实际可用的CPU及核心数量。Linux内核进程调度程序将多个进程在CPU核心上快速切换,从而给用户多个进程在同时运行的假象。(并发)
+
+ ### 相对优先级
+
+由于不是每个进程都与其他进程同样重要,可告知进程调度程序为不同的进程使用不同的调度策略。常规系统上运行的大多数进程所使用的的调度策略为SCHED_OTHER(也称为SCHED_NORMAL),但还有其他 一些调度策略用于不同的目的。SCHED_OTHER调度策略运行的进程的相对优先级称为进程的nice值, 可以有40种不同级别的nice值。
+
+在Linux中,决定一个进程的优先级的因素有两个,一个是PR值,一个是NICE值,PR值是由系统内核动态调控。而NICE值由我们用户自己决定。不过,PR值跟NICE值之间也是有一定的关联的。
+
+**NICE值的范围:**-20到19,数值越小,优先级越高
+
+**PR值的范围:**-99到39,其中0-39是与**NICE值**有着一定的对应关系
+
+进程默认启动时nice为0,优先级为20
+
+
+
+nice值越高表示优先级越低,例如19,该进程容易将CPU使用量让给其他进程
+
+nice值越低表示优先级越高,例如-20,该进程更倾向于不让出CPU
+
+### 10.1.1 查看进程的nice级别
+
+#### 10.1.1.1 使用ps查看
+
+```bash
+[root@localhost ~]# ps -axo pid,command,nice --sort=nice
+[root@localhost ~]# ps -axo pid,command,nice,cls --sort=-nice
+```
+
+TS表示该进程使用的调度策略为SCHED_OTHER
+
+#### 10.1.1.2 使用top查看
+
+NI:实际nice级别
+
+PR:将nice级别显示为映射到更大优先级队列,-20映射到0,+19映射到39
+
+#### 10.1.1.3 启动具有不同nice级别的进程
+
+启动进程的时候为进程指定nice值
+
+启动进程时,通常会继承父进程的nice级别,默认为0
+
+```sh
+[root@localhost ~]# nice -n -20 vim
+[root@localhost ~]# ps -axo command,pid,nice |grep vim
+```
+
+## 10.2 PRI
+
+在top命令中可以看到有PR这个数值,PR 和 nice 值,都会影响进程执行的优先级。PR 由 OS 内核动态调整,用户不能调整(PR 值越低,进程执行的优先级越高)。
+
+nice值用户可以自己调整,在用户调整了nice值后系统会通过如下公式来调整新的PR值,从而确定这个进程在系统中的优先级
+
+```shell
+PR(新) = PR(旧) + nice
+```
+
+PR值是OS动态调整的,但是PR的最终值还是需要由OS分析决定的
+
+#### 10.2.1 更改现有进程的nice级别
+
+调整进程的优先级(Nice Level) (-20高) - - - 0 - - - (19低)
+
+- 使用shell更改nice级别
+
+```bash
+[root@localhost ~]# vim
+[root@localhost ~]# ps -axo command,pid,nice |grep vim
+vim 1855 0
+grep --color=auto vim 1888 0
+[root@localhost ~]# renice -20 1855
+1855 (process ID) old priority 0, new priority -20
+[root@localhost ~]# ps -axo command,pid,nice |grep vim
+vim 1855 -20
+grep --color=auto vim 1895 0
+```
+
+# 11. jobs
+
+jobs 命令可以用来查看当前终端放入后台的任务
+
+```shell
+jobs [-lnprs] [任务声明 ...]
+```
+
+## 11.1 将任务放入到后台
+
+Linux 命令放入后台的方法有两种:
+
+* 在命令后面加入`空格 &`。使用这种方法放入后台的命令,在后台处于执行状态
+* 命令执行过裎中按 Ctrl+Z 快捷键,命令在后台处于暂停状态
+
+### 11.1.1 实例
+
+* 将任务放入后台,然后查看任务
+ * "+"号代表最近一个放入后台的工作,也是工作恢复时默认恢复的工作
+ * "-"号代表倒数第二个放入后台的工作
+
+```shell
+[root@localhost ~]# top &
+[root@localhost ~]# vi &
+[root@localhost ~]# ping baidu.com > /dev/null &
+# 让ping运行,但是不显示结果
+[root@localhost ~]# jobs
+[1] 已停止 top
+[2]- 已停止 vi
+[3]+ 运行中 ping baidu.com > /dev/null &
+```
+
+## 11.2 将任务恢复到前台
+
+fg 命令用于把后台工作恢复到前台执行
+
+```shell
+fg %工作号
+```
+
+注意,在使用此命令时,% 可以省略,但若将% 工作号全部省略,则此命令会将带有 + 号的工作恢复到前台。另外,使用此命令的过程中, % 可有可无。
+
+### 11.2.1 实例
+
+* 将top恢复到前台
+ * 命令虽然是对的,但是top这种需要交互的任务是无法后台的,所以也恢复不了
+
+```shell
+[root@localhost ~]# top &
+[1] 20584
+[root@localhost ~]# jobs
+[1]+ 已停止 top
+[root@localhost ~]# fg 1
+```
+
+## 11.3 后台任务恢复到后台运行
+
+前面讲过,使用`Ctrl+z`快捷键的方式,可以将前台工作放入后台,但是会处于暂停状态,可以使用bg命令
+
+```shell
+bg %工作号
+```
+
+这里的 % 同上,可以省略
+
+### 11.3.1 实例
+
+* 将ping命令暂停到后台,然后恢复后台运行
+
+```shell
+[root@localhost ~]# ping baidu.com > /dev/null
+^Z # 这边按下了Ctrl+z
+[1]+ 已停止 ping baidu.com > /dev/null
+[root@localhost ~]# jobs
+[1]+ 已停止 ping baidu.com > /dev/null
+[root@localhost ~]# bg %1
+[1]+ ping baidu.com > /dev/null &
+[root@localhost ~]# jobs
+[1]+ 运行中 ping baidu.com > /dev/null &
+```
+
+# 12. nohup
+
+虽然可以将程序放在后台运行,但是一旦关闭远程连接那么程序就会中断,如果我们想要将程序一直保持在后台运行,那么我们可以有如下三个选择:
+
+* 把需要在后台执行的命令加入`/etc/rc.local`文件,让系统在启动时执行这个后台程序。这种方法的问题是,服务器是不能随便重启的,如果有临时后台任务,就不能执行了
+* 使用系统定时任务,让系统在指定的时间执行某个后台命令。这样放入后台的命令与终端无关,是不依赖登录终端的
+* 使用 nohup 命令
+
+```shell
+nohup 命令 &
+```
+
+注意,这里的`&`表示此命令会在终端后台工作;反之,如果没有`&`,则表示此命令会在终端前台工作。
+
+## 12.1 实例
+
+* 让一个任务后台运行
+
+```shell
+[root@localhost ~]# nohup ping baidu.com &
+```
+
+我们退出远程连接,然后重新登录回来,会看到`ping baidu.com`依旧在运行,查看`~/nohup.out`文件可以看到程序执行输出的内容
+
+```shell
+[root@localhost ~]# ps aux |grep ping
+root 7157 0.0 0.0 149968 1988 ? S 14:12 0:00 ping baidu.com
+[root@localhost ~]# tail -f nohup.out
+```
+
diff --git a/01.Linux基础/08.进程管理/WPYNtDaMQ3fkYeQs.png!thumbnail b/01.Linux基础/08.进程管理/WPYNtDaMQ3fkYeQs.png!thumbnail
new file mode 100644
index 0000000..b5a0857
Binary files /dev/null and b/01.Linux基础/08.进程管理/WPYNtDaMQ3fkYeQs.png!thumbnail differ
diff --git a/01.Linux基础/08.进程管理/进程优先级.png b/01.Linux基础/08.进程管理/进程优先级.png
new file mode 100644
index 0000000..b41ba86
Binary files /dev/null and b/01.Linux基础/08.进程管理/进程优先级.png differ
diff --git a/01.Linux基础/09.存储管理.md b/01.Linux基础/09.存储管理.md
new file mode 100644
index 0000000..20afba8
--- /dev/null
+++ b/01.Linux基础/09.存储管理.md
@@ -0,0 +1,948 @@
+我们在计算机中保存的文件大都是保存在电脑硬盘中,部分同学还会将自己的文件存储在网盘中,网盘中的文件只能说是用来做备份,并不能像本地硬盘上的数据那样随时使用,我们在学习存储管理的时候主要学习的就是如何对自己计算机上的硬盘进行管理,目前我们主流的硬盘主要有两种形态,一种是及机械硬盘(HDD),一种是的固态硬盘(SSD)
+
+# 1. 硬盘工作原理
+
+## 1.1 机械硬盘HDD
+
+机械硬盘是靠机械马达以固定的速度转动磁盘,然后再有机械臂的摆动,让磁头可以读取盘片上的磁性信息,这种工作原理的硬盘我们成为机械硬盘。
+
+
+
+由于机械硬盘是依靠机械的运动来读写数据的,大家都知道机械在长时间运转的过程中是会产生一定的损耗,所以机械硬盘虽然理论上寿命很长,但随着时间的变长,机械磨损变大,导致磁头定位的误差变大,从而影响到硬盘的速度,这个就是为什么你的老电脑开机缓慢,运行卡顿的原因了。
+
+## 1.2 固态硬盘SSD
+
+固态硬盘依靠主控芯片来将数据的二进制信息写入浮栅晶体管中,以这样的原理实现数据的读取和写入。
+
+
+
+固态硬盘在读取和写入数据的时候完全是依靠数字电路实现的,所以并没有机械硬盘的机械磨损,而且也没有在磁盘上定位读写的延迟,所以固态硬盘的数据读写效率是远远高于机械硬盘的,但是也有一定的缺点,由于浮栅晶体管的设计原理,每次数据的读写,都会让浮栅晶体管所需要的电压更高,一定寿命以后,固态硬盘就会失效。并且固态硬盘如果发生了损坏,数据恢复的难度是大于机械硬盘的,所以为了可靠性,企业目前还是在大量使用机械硬盘的。
+
+
+
+
+
+
+
+# 2. 硬盘设备命名
+
+一台服务器往往会配备有多块硬盘,Linux中为了区分不同的硬盘,会使用不同的命名来将硬盘设备标识,Linux系统对物理磁盘设备会使用`sd[a-z]`的方式来命名。物理硬盘上的详细分区会使用数字的方式来进行标识,比如`sda`设备上的多个分区会标识为`sda[1,2,3....]`
+
+# 3. 分区表
+
+为了让系统能够识别和管理物理设备上的不同分区,需要在物理设备前加上一些数据用于记录分区的情况,这些数据就是分区表数据,目前分区表有两种主流的格式:
+
+* MBR
+ * 管理的硬盘大小不能超过2T
+ * 有主分区和扩展分区两种,不管是哪种分区,总数不能超过4个分区
+ * 扩展分区内部可以逻辑上划分多个区域,但是在分区表中都算在一个分区内
+ * 如果作为系统盘,必须要设置一个激活分区,用于存放系统的引导文件
+
+
+
+* GPT
+ * 管理硬盘大小不能超过18EB,目前人类还没制造出单块这么大的硬盘
+ * 理论上支持无限分区,在win10系统上,最多可以分128个分区
+ * 如果作为系统盘,**必须要创建一个EFI分区,用于存放系统的引导文件**建议ESP分区512M,对齐8扇区4096字节
+
+
+
+
+
+电脑启动的时候:
+
+MBR分区表会找到激活分区,从里面加载系统启动;
+
+GPT分区表会查找EFI分区,没有是开不了机的,所以GPT分区表情况下需要建立ESP,MSR分区。
+
+MSR是微软保留的引导分区,分区一般不会坏因此一般不需要。
+
+ESP建立512MB,对齐到扇区整数倍是指一次读写几个扇区(例如新建个txt只写一个字符,依旧占用4K,除非越写越大超过4K,占4K的整数倍),并不是越大越好也不是越小越好,根据实际需求,一般是4KB。
+
+# 4. 管理分区
+
+- 列出块设备
+
+```bash
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+sda 8:0 0 50G 0 disk
+├─sda1 8:1 0 1G 0 part /boot
+└─sda2 8:2 0 49G 0 part
+ ├─centos-root 253:0 0 47G 0 lvm /
+ └─centos-swap 253:1 0 2G 0 lvm [SWAP]
+sdb 8:16 0 20G 0 disk
+sdc 8:32 0 20G 0 disk
+sr0 11:0 1 1024M 0 rom
+```
+
+- 创建分区命令
+
+```bash
+fdisk 管理MBR分区
+gdisk 管理GPT分区
+parted 高级分区操作
+```
+
+- 重新设置内存中的内核分区表版本
+
+```bash
+partprobe
+```
+
+## 4.1 parted 命令
+
+- parted的操作都是实时生效的,小心使用
+- 格式:
+
+```bash
+parted [选项]... [设备 [命令 [参数]...]...]
+```
+
+- 操作命令:
+
+```bash
+cp [FROM-DEVICE] FROM-MINOR TO-MINOR #将文件系统复制到另一个分区
+help [COMMAND] #打印通用求助信息,或关于 COMMAND 的信息
+mklabel 标签类型 #创建新的磁盘标签 (分区表)
+mkfs MINOR 文件系统类型 #在 MINOR 创建类型为“文件系统类型”的文件系统
+mkpart 分区类型 [文件系统类型] 起始点 终止点 #创建一个分区
+mkpartfs 分区类型 文件系统类型 起始点 终止点 #创建一个带有文件系统的分区
+move MINOR 起始点 终止点 #移动编号为 MINOR 的分区
+name MINOR 名称 #将编号为 MINOR 的分区命名为“名称”
+print [MINOR] #打印分区表,或者分区
+quit #退出程序
+rescue 起始点 终止点 #挽救临近“起始点”、“终止点”的遗失的分区
+resize MINOR 起始点 终止点 #改变位于编号为 MINOR 的分区中文件系统的大小
+rm MINOR #删除编号为 MINOR 的分区
+select 设备 #选择要编辑的设备
+set MINOR 标志 状态 #改变编号为 MINOR 的分区的标志
+```
+
+- 查看分区情况
+
+```bash
+[root@localhost ~]# parted /dev/nvme0n1 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n1: 21.5GB
+Sector size (logical/physical): 512B/512B
+Partition Table: msdos
+Disk Flags:
+
+Number Start End Size Type File system Flags
+ 1 1049kB 1075MB 1074MB primary xfs boot
+ 2 1075MB 21.5GB 20.4GB primary lvm
+
+[root@localhost ~]# parted /dev/nvme0n2 print
+Error: /dev/nvme0n2: unrecognised disk label
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n2: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: unknown
+Disk Flags:
+```
+
+- 设置磁盘的分区表
+
+```bash
+# [root@localhost ~]# parted /dev/nvme0n2 mklabel msdos
+[root@localhost ~]# parted /dev/nvme0n2 mklabel gpt
+Information: You may need to update /etc/fstab.
+
+[root@localhost ~]# parted /dev/nvme0n2 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n2: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+# 由于没有分区,所有没有具体的分区信息
+```
+
+- 对磁盘进行分区
+
+```bash
+[root@localhost ~]# parted /dev/nvme0n2 mkpart primary 1 1G
+# 创建1个G大小的分区
+Information: You may need to update /etc/fstab.
+[root@localhost ~]# parted /dev/nvme0n2 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n2: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+ 1 1049kB 1000MB 999MB primary
+
+```
+
+- 删除分区
+
+```bash
+[root@localhost ~]# parted /dev/nvme0n2 rm 1
+Information: You may need to update /etc/fstab.
+
+[root@localhost ~]# parted /dev/nvme0n2 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n2: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+```
+
+- 修改磁盘为mbr分区,注意会丢失所有数据
+
+```bash
+[root@localhost ~]# parted /dev/nvme0n2 mklabel msdos
+警告: The existing disk label on /dev/nvme0n2 will be destroyed and all data on this disk will be lost. Do
+you want to continue?
+是/Yes/否/No? yes
+信息: You may need to update /etc/fstab.
+```
+
+## 4.2 fdisk工具
+
+管理磁盘中MBR分区
+
+`fdisk [磁盘名称]`
+
+fdisk命令中的参数以及作用
+
+| 参数 | 作用 |
+| ---- | ---------------------- |
+| m | 查看全部可用的参数 |
+| n | 添加新的分区 |
+| d | 删除某个分区信息 |
+| l | 列出所有可用的分区类型 |
+| t | 改变某个分区的类型 |
+| p | 查看分区信息 |
+| w | 保存并退出 |
+| q | 不保存直接退出 |
+
+
+
+```bash
+[root@localhost ~]# fdisk /dev/nvme0n2
+
+Welcome to fdisk (util-linux 2.37.4).
+Changes will remain in memory only, until you decide to write them.
+Be careful before using the write command.
+
+Device does not contain a recognized partition table.
+Created a new DOS disklabel with disk identifier 0x447f44d1.
+
+Command (m for help): n
+Partition type
+ p primary (0 primary, 0 extended, 4 free)
+ e extended (container for logical partitions)
+Select (default p): p
+Partition number (1-4, default 1):
+First sector (2048-10485759, default 2048):
+Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-10485759, default 10485759): +1G
+
+Created a new partition 1 of type 'Linux' and of size 1 GiB.
+
+Command (m for help): p
+Disk /dev/nvme0n2: 5 GiB, 5368709120 bytes, 10485760 sectors
+Disk model: VMware Virtual NVMe Disk
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / 512 bytes
+Disklabel type: dos
+Disk identifier: 0x447f44d1
+
+Device Boot Start End Sectors Size Id Type
+/dev/nvme0n2p1 2048 2099199 2097152 1G 83 Linux
+
+Command (m for help): w
+The partition table has been altered.
+Calling ioctl() to re-read partition table.
+Syncing disks.
+
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─nvme0n2p1 259:8 0 1G 0 part
+nvme0n3 259:4 0 5G 0 disk
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+```
+
+## 4.3 gdisk工具
+
+管理磁盘中的GPT分区
+
+使用方式和选项与fdisk中几乎一致
+
+# 5. 存储结构与磁盘划分
+
+Linux系统中常见的目录名称以及相应内容
+
+| 目录名称 | 应放置文件的内容 |
+| ----------- | --------------------------------------------------------- |
+| /boot | 开机所需文件—内核、开机菜单以及所需配置文件等 |
+| /dev | 以文件形式存放任何设备与接口 |
+| /etc | 配置文件 |
+| /home | 用户家目录 |
+| /bin | 存放单用户模式下还可以操作的命令 |
+| /lib | 开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数 |
+| /sbin | 开机过程中需要的命令 |
+| /media | 用于挂载设备文件的目录 |
+| /opt | 放置第三方的软件 |
+| /root | 系统管理员的家目录 |
+| /srv | 一些网络服务的数据文件目录 |
+| /tmp | 任何人均可使用的“共享”临时目录 |
+| /proc | 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等 |
+| /usr/local | 用户自行安装的软件 |
+| /usr/sbin | Linux系统开机时不会使用到的软件/命令/脚本 |
+| /usr/share | 帮助与说明文件,也可放置共享文件 |
+| /var | 主要存放经常变化的文件,如日志 |
+| /lost+found | 当文件系统发生错误时,将一些丢失的文件片段存放在这里 |
+
+表示路径的方式:
+
+- 绝对路径指的是从根目录(/)开始写起的文件或目录名称
+- 相对路径则指的是相对于当前路径的写法
+
+# 6. 物理设备的命名规则
+
+常见的硬件设备及其文件名称
+
+| 硬件设备 | 文件名称 |
+| ------------- | ------------------ |
+| IDE设备 | /dev/hd[a-d] |
+| SCSI/SATA/U盘 | /dev/sd[a-p] |
+| 软驱 | /dev/fd[0-1] |
+| 打印机 | /dev/lp[0-15] |
+| 光驱 | /dev/cdrom |
+| 鼠标 | /dev/mouse |
+| 磁带机 | /dev/st0或/dev/ht0 |
+
+一般的硬盘设备都会是以“/dev/sd”开头,分区编号按照如下规则:
+
+- 主分区或扩展分区的编号从1开始,到4结束;
+- 逻辑分区从编号5开始。
+
+设备文件名称:
+
+
+
+# 7. 文件系统与数据资料
+
+当我们对一块硬盘分区好了以后,接下来我们还要做一件事情,就是我们要对这个分区做一个规定。也可以理解为,当我们要在这个分区上面存放数据的时候,应该按照什么样的规律存放,或者是读取的时候,应该按照什么样的规律读取。
+
+这样对磁盘或者分区的规定,我们就称之为文件系统。
+
+文件系统的作用是合理规划硬盘,以保证用户正常的使用需求。Linux系统支持数十种的文件系统。但是从大的角度上来看,其实主要分为日志式文件系统和索引式文件系统两种。
+
+
+
+
+
+## 7.1 Linux常见的文件系统
+
+| 文件系统 | 解释 |
+| -------- | ------------------------------------------------------------ |
+| Ext3 | 是一款日志文件系统,能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。然而,当硬盘容量较大时,所需的修复时间也会很长,而且也不能百分之百地保证资料不会丢失。它会把整个磁盘的每个写入动作的细节都预先记录下来,以便在发生异常宕机后能回溯追踪到被中断的部分,然后尝试进行修复。 |
+| Ext4 | Ext3的改进版本,作为RHEL 6系统中的默认文件管理系统,它支持的存储容量高达1EB(1EB=1,073,741,824GB),且能够有无限多的子目录。另外,Ext4文件系统能够批量分配block块,从而极大地提高了读写效率。 |
+| XFS | 是一种高性能的日志文件系统,而且是RHEL 7中默认的文件管理系统,它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只用花费极低的计算和存储性能。并且它最大可支持的存储容量为18EB,这几乎满足了所有需求。 |
+
+格式化后会发生如下事情
+
+- 日志式文件系统先干掉inode表,索引式文件系统先干掉第一个索引,表示空间可用。
+
+- Linux创建一个硬盘地图'superblock',记录此filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
+- inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block 号码,默认一个inode表格128字节,一个block记录消耗4B,记录满了后会新建inode用于扩展。
+ - 该文件的访问权限(read、write、execute);
+ - 该文件的所有者与所属组(owner、group);
+ - 该文件的大小(size);
+ - 该文件的创建或内容修改时间(ctime);
+ - 该文件的最后一次访问时间(atime);
+ - 该文件的修改时间(mtime);
+ - 文件的特殊权限(SUID、SGID、SBIT);
+ - 该文件的真实数据地址(point)。
+- block:用于存储数据
+
+计算机系统在发展过程中产生了众多的文件系统,为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux内核中的软件层为用户程序提供了一个VFS(Virtual File System,虚拟文件系统)接口,这样用户实际上在操作文件时就是统一对这个虚拟文件系统进行操作了。
+
+
+
+## 7.2 mkfs工具
+
+Linux mkfs(英文全拼:make file system)命令用于在特定的分区上建立 linux 文件系统。
+
+**格式:**
+
+```bash
+mkfs [-V] [-t fstype] [fs-options] filesys [blocks]
+```
+
+选项:
+
+- device : 预备检查的硬盘分区,例如:/dev/nvme0n1p1
+- -V : 详细显示模式
+- -c : 在制做档案系统前,检查该partition 是否有坏轨
+- -l bad_blocks_file : 将有坏轨的block资料加到 bad_blocks_file 里面
+- block : 给定 block 的大小
+
+**实例:使用parted分区,然后使用mkfs创建ext4文件系统**
+
+```bash
+[root@localhost ~]# parted /dev/nvme0n3 mklabel gpt
+[root@localhost ~]# parted /dev/nvme0n3 mkpart primary 1 1G
+Information: You may need to update /etc/fstab.
+[root@localhost ~]# parted /dev/nvme0n3 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n3: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+ 1 1049kB 1000MB 999MB primary
+
+[root@localhost ~]# mkfs.ext4 /dev/nvme0n3p1
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 243968 4k blocks and 61056 inodes
+Filesystem UUID: db15a3c8-ae5d-4e69-aa93-cc0ee4107547
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (4096 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# parted /dev/nvme0n3 print
+Model: VMware Virtual NVMe Disk (nvme)
+Disk /dev/nvme0n3: 5369MB
+Sector size (logical/physical): 512B/512B
+Partition Table: gpt
+Disk Flags:
+
+Number Start End Size File system Name Flags
+ 1 1049kB 1000MB 999MB ext4 primary
+```
+
+## 7.3 mount挂载
+
+挂载文件系统`mount 文件系统 挂载目录`
+
+mount命令中的参数以及作用
+
+| 参数 | 作用 |
+| ---- | ------------------------------------ |
+| -a | 挂载所有在/etc/fstab中定义的文件系统 |
+| -t | 指定文件系统的类型 |
+
+临时挂载文件系统
+
+系统在重启后挂载就会失效
+
+```bash
+[root@node-1 ~]# mkdir backup
+[root@node-1 ~]# mount /dev/sda2 /root/backup
+```
+
+如果想让硬件设备和目录永久地进行自动关联,就必须把挂载信息按照指定的填写格式“设备文件 挂载目录 格式类型 权限选项 是否备份 是否自检”,写入到/etc/fstab文件中。
+
+用于挂载信息的指定填写格式中,各字段所表示的意义
+
+| 字段 | 意义 |
+| -------- | ------------------------------------------------------------ |
+| 设备文件 | 一般为设备的路径+设备名称,也可以写唯一识别码(UUID,Universally Unique Identifier) |
+| 挂载目录 | 指定要挂载到的目录,需在挂载前创建好 |
+| 格式类型 | 指定文件系统的格式,比如Ext3、Ext4、XFS、SWAP、iso9660(此为光盘设备)等 |
+| 权限选项 | 若设置为defaults,则默认权限为:rw, suid, dev, exec, auto, nouser, async |
+| 是否备份 | 若为1则开机后使用dump进行磁盘备份,为0则不备份 |
+| 是否自检 | 若为1则开机后自动进行磁盘自检,为0则不自检 |
+
+- 实例,挂载分区`/dev/sdb1`到`/mnt/volume1`下,并且设置为永久自动挂载
+
+```bash
+[root@localhost ~]# mkdir -p /mnt/volume1
+[root@localhost ~]# mount /dev/sdb1 /mnt/volume1
+[root@localhost ~]# df -h
+文件系统 容量 已用 可用 已用% 挂载点
+/dev/mapper/centos-root 47G 995M 46G 3% /
+devtmpfs 979M 0 979M 0% /dev
+tmpfs 991M 0 991M 0% /dev/shm
+tmpfs 991M 8.5M 982M 1% /run
+tmpfs 991M 0 991M 0% /sys/fs/cgroup
+/dev/sda1 1014M 133M 882M 14% /boot
+tmpfs 199M 0 199M 0% /run/user/0
+/dev/sdb1 9.1G 37M 8.6G 1% /mnt/volume1
+# 先卸载sdb1
+[root@localhost ~]# umount /dev/sdb1
+[root@localhost ~]# vim /etc/fstab
+# 最后一行加上
+/dev/sdb1 /mnt/volume1 ext4 defaults 0 0
+
+[root@localhost ~]# mount -a
+# 测试是否正确配置,fstab上的设备挂一遍试试看,万一错了重启系统会失败。
+[root@localhost ~]# df -h
+文件系统 容量 已用 可用 已用% 挂载点
+/dev/mapper/centos-root 47G 995M 46G 3% /
+devtmpfs 979M 0 979M 0% /dev
+tmpfs 991M 0 991M 0% /dev/shm
+tmpfs 991M 8.5M 982M 1% /run
+tmpfs 991M 0 991M 0% /sys/fs/cgroup
+/dev/sda1 1014M 133M 882M 14% /boot
+tmpfs 199M 0 199M 0% /run/user/0
+/dev/sdb1 9.1G 37M 8.6G 1% /mnt/volume1
+```
+
+## 7.4 umount
+
+撤销已经挂载的设备文件`umount [挂载点/设备文件]`
+
+```bash
+[root@node-1 ~]# umount /dev/sda2
+```
+
+挂载实验:
+
+```shell
+#进行了格式化后
+#[root@localhost ~]# mkfs.ext4 /dev/sdb1
+#未挂载sdb1前,此时file0创建在sda1上
+[root@localhost ~]# mkdir /mnt/disk1
+[root@localhost ~]# touch /mnt/disk1/file0
+[root@localhost ~]# ll /mnt/disk1/
+-rw-r--r-- 1 root root 0 6月 9 19:44 file0
+#挂载sdb1,file0消失
+[root@localhost ~]# mount /dev/sdb1 /mnt/disk1/
+[root@localhost ~]# ll /mnt/disk1/
+drwx------ 2 root root 16384 6月 9 19:42 lost+found
+#此时file0创建在sda1
+[root@localhost ~]# touch /mnt/disk1/file1
+[root@localhost ~]# ll /mnt/disk1/
+-rw-r--r-- 1 root root 0 6月 9 19:48 file1
+drwx------ 2 root root 16384 6月 9 19:42 lost+found
+#卸载sdb1,file1消失,file0出现
+[root@localhost ~]# umount /dev/sdb1
+[root@localhost ~]# ll /mnt/disk1/
+-rw-r--r-- 1 root root 0 6月 9 19:44 file0
+```
+
+## 7.5 df
+
+用于显示文件系统的磁盘空间使用情况
+
+`df [选项]`
+
+常用选项
+
+- `-h`:以人类可读的格式显示磁盘空间,使用K、M、G等单位。
+- `-T`:显示文件系统类型。
+
+```bash
+[root@localhost ~]# df -h
+文件系统 容量 已用 可用 已用% 挂载点
+/dev/mapper/centos-root 47G 995M 46G 3% /
+devtmpfs 979M 0 979M 0% /dev
+tmpfs 991M 0 991M 0% /dev/shm
+tmpfs 991M 8.5M 982M 1% /run
+tmpfs 991M 0 991M 0% /sys/fs/cgroup
+/dev/sda1 1014M 133M 882M 14% /boot
+tmpfs 199M 0 199M 0% /run/user/0
+/dev/sdb1 9.1G 37M 8.6G 1% /mnt/volume1
+```
+
+## 7.6 du
+
+查看某个目录下文件数据的占用量
+
+`du [选项] [文件]`
+
+```bash
+[root@localhost ~]# du -sh /etc
+23M /etc
+```
+
+# 8. 添加交换分区
+
+SWAP(交换)分区是一种通过在硬盘中预先划分一定的空间,然后将把内存中暂时不常用的数据临时存放到硬盘中,以便腾出物理内存空间让更活跃的程序服务来使用的技术
+
+在生产环境中,交换分区的大小一般为真实物理内存的1.5~2倍
+
+```bash
+[root@localhost ~]# mkswap /dev/nvme0n2p1
+Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
+no label, UUID=9d5158b3-9a30-4a0a-8167-7ee1bc9ce4f8
+[root@localhost ~]# free -h
+ total used free shared buff/cache available
+Mem: 1.7Gi 448Mi 1.2Gi 6.0Mi 201Mi 1.3Gi
+Swap: 2.0Gi 0B 2.0Gi
+[root@localhost ~]# swapon /dev/nvme0n2p1 # 挂载swap交换分区
+[root@localhost ~]# vim /etc/fstab # 写入fstab文件中永久挂载
+#
+# /etc/fstab
+# Created by anaconda on Sat Nov 9 02:51:16 2024
+#
+# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
+# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
+#
+# After editing this file, run 'systemctl daemon-reload' to update systemd
+# units generated from this file.
+#
+/dev/mapper/rl-root / xfs defaults 0 0
+UUID=12fcea99-d1db-4f0a-ad86-f03129024fdb /boot xfs defaults 0 0
+/dev/mapper/rl-swap none swap defaults 0 0
+/dev/nvme0n2p1 swap swap defaults 0 0
+
+[root@localhost ~]# free -h
+ total used free shared buff/cache available
+Mem: 1.7Gi 451Mi 1.2Gi 6.0Mi 205Mi 1.3Gi
+Swap: 3.0Gi 0B 3.0Gi
+```
+
+# 9. 磁盘容量配额
+
+简单理解就是可以通过磁盘配额限制某个用户能够使用多大的空间
+
+## 9.1 quota
+
+### 9.1.1 实例切入
+
+描述:
+
+- 创建5个用户user1,user2,user3,user4,user5,密码和用户名相同,初始组为usergrp组。
+- 5个用户都可以取得300M的磁盘使用空间,文件数量不限。超过250M,给于提示。
+
+### 9.1.2 准备磁盘
+
+- 创建分区
+
+```bash
+[root@localhost ~]# fdisk /dev/nvme0n2
+
+Welcome to fdisk (util-linux 2.37.4).
+Changes will remain in memory only, until you decide to write them.
+Be careful before using the write command.
+
+Device does not contain a recognized partition table.
+Created a new DOS disklabel with disk identifier 0x27819a3d.
+
+Command (m for help): n
+Partition type
+ p primary (0 primary, 0 extended, 4 free)
+ e extended (container for logical partitions)
+Select (default p):
+
+Using default response p.
+Partition number (1-4, default 1):
+First sector (2048-10485759, default 2048):
+Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-10485759, default 10485759): +2G
+
+Created a new partition 1 of type 'Linux' and of size 2 GiB.
+
+Command (m for help): p
+Disk /dev/nvme0n2: 5 GiB, 5368709120 bytes, 10485760 sectors
+Disk model: VMware Virtual NVMe Disk
+Units: sectors of 1 * 512 = 512 bytes
+Sector size (logical/physical): 512 bytes / 512 bytes
+I/O size (minimum/optimal): 512 bytes / 512 bytes
+Disklabel type: dos
+Disk identifier: 0x27819a3d
+
+Device Boot Start End Sectors Size Id Type
+/dev/nvme0n2p1 2048 4196351 4194304 2G 83 Linux
+
+Command (m for help): w
+The partition table has been altered.
+Calling ioctl() to re-read partition table.
+Syncing disks.
+```
+
+- lsblk 查看当前分区情况
+
+```bash
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─nvme0n2p1 259:8 0 2G 0 part
+nvme0n3 259:4 0 5G 0 disk
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+```
+
+- 格式化分区的文件系统
+
+```bash
+[root@localhost ~]# mkfs.ext4 /dev/nvme0n2p1
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 524288 4k blocks and 131072 inodes
+Filesystem UUID: da4f8f5c-6867-4cf8-8486-333a16adbcdb
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+```
+
+- 创建目录并挂载
+
+```bash
+[root@localhost ~]# mkdir /mnt/mountpoint
+[root@localhost ~]# mount /dev/nvme0n2p1 /mnt/mountpoint
+[root@localhost ~]# df -Th
+Filesystem Type Size Used Avail Use% Mounted on
+devtmpfs devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs tmpfs 872M 0 872M 0% /dev/shm
+tmpfs tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root xfs 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 xfs 960M 261M 700M 28% /boot
+tmpfs tmpfs 175M 0 175M 0% /run/user/0
+/dev/nvme0n2p1 ext4 2.0G 24K 1.8G 1% /mnt/mountpoint
+```
+
+### 9.1.3 准备用户
+
+```bash
+[root@atopos ~]# setenforce 0
+# 临时关闭SELinux
+[root@atopos ~]# getenforce
+Permissive
+[root@atopos ~]# groupadd usergrp
+[root@atopos ~]# for i in {1..5}; do useradd -g usergrp -b /mnt/mountpoint user$i; done
+```
+
+### 9.1.4 确保文件系统支持
+
+- 检查挂载点是否支持quota配置
+
+```bash
+[root@localhost ~]# mount | grep mountpoint
+/dev/nvme0n2p1 on /mnt/mountpoint type ext4 (rw,relatime,seclabel)
+```
+
+- 重新挂载,让文件系统支持quota配置
+
+```bash
+[root@localhost ~]# mount -o remount,usrquota,grpquota /mnt/mountpoint/
+[root@localhost ~]# mount | grep mountpoint
+/dev/nvme0n2p1 on /mnt/mountpoint type ext4 (rw,relatime,seclabel,quota,usrquota,grpquota)
+```
+
+### 9.1.5 安装 quota
+
+- 软限制:当达到软限制时会提示用户,但仍允许用户在限定的额度内继续使用。
+- 硬限制:当达到硬限制时会提示用户,且强制终止用户的操作。
+
+quotacheck主要参数
+
+- -a:扫描所有在/etc/mtab内含有quota参数的文件系统
+- -u:针对用户扫描文件与目录的使用情况,会新建一个aquota.user文件
+- -g:针对用户组扫描文件与目录的使用情况,会新增一个aquota.group文件
+- -v:显示扫描过程的信息
+
+```bash
+[root@atopos ~]# yum install -y quota
+```
+
+### 9.1.6 开启 quota
+
+```bash
+[root@localhost ~]# quotacheck -avug
+quotacheck: Your kernel probably supports ext4 quota feature but you are using external quota files. Please switch your filesystem to use ext4 quota feature as external quota files on ext4 are deprecated.
+quotacheck: Scanning /dev/nvme0n2p1 [/mnt/mountpoint] done
+quotacheck: Cannot stat old user quota file /mnt/mountpoint/aquota.user: No such file or directory. Usage will not be subtracted.
+quotacheck: Cannot stat old group quota file /mnt/mountpoint/aquota.group: No such file or directory. Usage will not be subtracted.
+quotacheck: Cannot stat old user quota file /mnt/mountpoint/aquota.user: No such file or directory. Usage will not be subtracted.
+quotacheck: Cannot stat old group quota file /mnt/mountpoint/aquota.group: No such file or directory. Usage will not be subtracted.
+quotacheck: Checked 8 directories and 15 files
+quotacheck: Old file not found.
+quotacheck: Old file not found.
+[root@localhost ~]# quotaon -avug
+quotaon: Your kernel probably supports ext4 quota feature but you are using external quota files. Please switch your filesystem to use ext4 quota feature as external quota files on ext4 are deprecated.
+/dev/nvme0n2p1 [/mnt/mountpoint]: group quotas turned on
+/dev/nvme0n2p1 [/mnt/mountpoint]: user quotas turned on
+```
+
+### 9.1.7 编辑配额配置
+
+```bash
+[root@localhost ~]# edquota -u user1
+```
+
+
+
+- 可以将针对user1的限制复制给user2
+
+```sh
+[root@localhost ~]# edquota -p user1 -u user2
+```
+
+- 查看限制情况
+
+```bash
+[root@localhost ~]# repquota -as
+*** Report for user quotas on device /dev/nvme0n2p1
+Block grace time: 7days; Inode grace time: 7days
+ Space limits File limits
+User used soft hard grace used soft hard grace
+----------------------------------------------------------------------
+root -- 20K 0K 0K 2 0 0
+user1 -- 16K 245M 293M 4 0 0
+user2 -- 16K 245M 293M 4 0 0
+user3 -- 16K 0K 0K 4 0 0
+user4 -- 16K 0K 0K 4 0 0
+user5 -- 16K 0K 0K 4 0 0
+```
+
+### 9.1.8 测试
+
+```bash
+# user1用户测试
+[root@localhost ~]# su - user1
+[user1@localhost ~]$ dd if=/dev/zero of=bigfile bs=10M count=50
+nvme0n2p1: warning, user block quota exceeded.
+nvme0n2p1: write failed, user block limit reached.
+dd: error writing 'bigfile': Disk quota exceeded
+30+0 records in
+29+0 records out
+307179520 bytes (307 MB, 293 MiB) copied, 1.1834 s, 260 MB/s
+[user1@localhost ~]$ du -sh
+293M .
+
+# user2用户测试
+[root@localhost ~]# su - user2
+[user2@localhost ~]$ dd if=/dev/zero of=bigfile bs=10M count=50
+nvme0n2p1: warning, user block quota exceeded.
+nvme0n2p1: write failed, user block limit reached.
+dd: error writing 'bigfile': Disk quota exceeded
+30+0 records in
+29+0 records out
+307183616 bytes (307 MB, 293 MiB) copied, 1.43269 s, 214 MB/s
+[user2@localhost ~]$ du -sh
+293M .
+```
+
+### 9.1.9 quota 命令
+
+Linux quota命令用于显示磁盘已使用的空间与限制。
+
+执行quota指令,可查询磁盘空间的限制,并得知已使用多少空间
+
+选项:
+
+- -g 列出群组的磁盘空间限制。
+- -q 简明列表,只列出超过限制的部分。
+- -u 列出用户的磁盘空间限制。
+- -v 显示该用户或群组,在所有挂入系统的存储设备的空间限制。
+- -V 显示版本信息。
+
+## 9.2 xfs_quota
+
+专门针对XFS文件系统来管理quota磁盘容量配额服务
+
+`xfs_quota [参数] 配额 文件系统`
+
+- \-c参数用于以参数的形式设置要执行的命令
+
+- \-x参数是专家模式
+
+硬盘使用量的软限制和硬限制分别为3MB和6MB;创建文件数量的软限制和硬限制分别为3个和6个。
+
+```bash
+[root@localhost ~]# xfs_quota -x -c 'limit bsoft=3m bhard=6m isoft=3 ihard=6 test' /boot
+[root@localhost ~]# xfs_quota -x -c report /boot
+User quota on /boot (/dev/sda1)
+ Blocks
+User ID Used Soft Hard Warn/Grace
+---------- --------------------------------------------------
+root 115516 0 0 00 [--------]
+test 0 3072 6144 00 [--------]
+```
+
+```bash
+[root@localhost ~]# su - test
+[test@localhost ~]$ dd if=/dev/zero of=/boot/tom bs=5M count=1
+1+0 records in
+1+0 records out
+5242880 bytes (5.2 MB) copied, 0.00350676 s, 1.5 GB/s
+[test@localhost ~]$ dd if=/dev/zero of=/boot/tom bs=8M count=1
+dd: error writing ‘/boot/tom’: Disk quota exceeded
+1+0 records in
+0+0 records out
+4194304 bytes (4.2 MB) copied, 0.00760235 s, 552 MB/s
+```
+
+# 10. 软硬方式链接
+
+在Linux系统中存在硬链接和软连接两种文件。
+
+- 硬链接(hard link):
+ - 可以将它理解为一个“指向原始文件inode的指针”,系统不为它分配独立的inode和文件。所以,硬链接文件与原始文件其实是同一个文件,只是名字不同。我们每添加一个硬链接,该文件的inode连接数就会增加1;而且只有当该文件的inode连接数为0时,才算彻底将它删除。换言之,由于硬链接实际上是指向原文件inode的指针,因此即便原始文件被删除,依然可以通过硬链接文件来访问。需要注意的是,由于技术的局限性,我们不能跨分区对目录文件进行链接。
+- 软链接(也称为符号链接[symbolic link]):
+ - 仅仅包含所链接文件的路径名,因此能链接目录文件,也可以跨越文件系统进行链接。但是,当原始文件被删除后,链接文件也将失效,从这一点上来说与Windows系统中的“快捷方式”具有一样的性质。
+
+## 10.1 ln
+
+用于创建链接文件
+
+`ln [选项] 目标`
+
+ln命令中可用的参数以及作用
+
+| 参数 | 作用 |
+| ---- | -------------------------------------------------- |
+| -s | 创建“符号链接”(如果不带-s参数,则默认创建硬链接) |
+| -f | 强制创建文件或目录的链接 |
+| -i | 覆盖前先询问 |
+| -v | 显示创建链接的过程 |
+
+### 10.1.1 软链接演示
+
+```bash
+[root@localhost ~]# echo "hello linux" > testfile
+[root@localhost ~]# ln -s testfile linkfile # 创建软连接
+[root@localhost ~]# ll
+total 8
+-rw-------. 1 root root 905 Nov 9 10:57 anaconda-ks.cfg
+lrwxrwxrwx. 1 root root 8 Nov 15 20:41 linkfile -> testfile
+-rw-r--r--. 1 root root 12 Nov 15 20:40 testfile
+[root@localhost ~]# cat linkfile
+hello linux
+[root@localhost ~]# ls -l linkfile
+lrwxrwxrwx. 1 root root 8 Nov 15 20:41 linkfile -> testfile
+[root@localhost ~]# rm -f testfile
+[root@localhost ~]# cat linkfile
+cat: linkfile: No such file or directory
+```
+
+### 10.1.2 硬链接演示
+
+```bash
+[root@localhost ~]# echo "hello linux" > testfile
+[root@localhost ~]# ln testfile linkfile
+[root@localhost ~]# cat linkfile
+hello linux
+[root@localhost ~]# ls -l linkfile
+-rw-r--r--. 2 root root 12 Nov 15 20:42 linkfile
+[root@localhost ~]# rm -f testfile
+[root@localhost ~]# cat linkfile
+hello linux
+```
+
diff --git a/01.Linux基础/09.存储管理/MBR分区表.png b/01.Linux基础/09.存储管理/MBR分区表.png
new file mode 100644
index 0000000..bed4ea9
Binary files /dev/null and b/01.Linux基础/09.存储管理/MBR分区表.png differ
diff --git a/01.Linux基础/09.存储管理/gpt分区表.png b/01.Linux基础/09.存储管理/gpt分区表.png
new file mode 100644
index 0000000..ff64873
Binary files /dev/null and b/01.Linux基础/09.存储管理/gpt分区表.png differ
diff --git a/01.Linux基础/09.存储管理/分区操作.gif b/01.Linux基础/09.存储管理/分区操作.gif
new file mode 100644
index 0000000..6ac3b18
Binary files /dev/null and b/01.Linux基础/09.存储管理/分区操作.gif differ
diff --git a/01.Linux基础/09.存储管理/分区演示.png b/01.Linux基础/09.存储管理/分区演示.png
new file mode 100644
index 0000000..3ed22ea
Binary files /dev/null and b/01.Linux基础/09.存储管理/分区演示.png differ
diff --git a/01.Linux基础/09.存储管理/固态硬盘ssd.png b/01.Linux基础/09.存储管理/固态硬盘ssd.png
new file mode 100644
index 0000000..2446da2
Binary files /dev/null and b/01.Linux基础/09.存储管理/固态硬盘ssd.png differ
diff --git a/01.Linux基础/09.存储管理/固态硬盘设计1.png b/01.Linux基础/09.存储管理/固态硬盘设计1.png
new file mode 100644
index 0000000..b00820a
Binary files /dev/null and b/01.Linux基础/09.存储管理/固态硬盘设计1.png differ
diff --git a/01.Linux基础/09.存储管理/固态硬盘设计2.png b/01.Linux基础/09.存储管理/固态硬盘设计2.png
new file mode 100644
index 0000000..6a6c3e4
Binary files /dev/null and b/01.Linux基础/09.存储管理/固态硬盘设计2.png differ
diff --git a/01.Linux基础/09.存储管理/固态硬盘设计3.png b/01.Linux基础/09.存储管理/固态硬盘设计3.png
new file mode 100644
index 0000000..7bb3e8e
Binary files /dev/null and b/01.Linux基础/09.存储管理/固态硬盘设计3.png differ
diff --git a/01.Linux基础/09.存储管理/日志文件系统1.png b/01.Linux基础/09.存储管理/日志文件系统1.png
new file mode 100644
index 0000000..016be3b
Binary files /dev/null and b/01.Linux基础/09.存储管理/日志文件系统1.png differ
diff --git a/01.Linux基础/09.存储管理/日志文件系统2.png b/01.Linux基础/09.存储管理/日志文件系统2.png
new file mode 100644
index 0000000..835e8df
Binary files /dev/null and b/01.Linux基础/09.存储管理/日志文件系统2.png differ
diff --git a/01.Linux基础/09.存储管理/机械硬盘hdd.png b/01.Linux基础/09.存储管理/机械硬盘hdd.png
new file mode 100644
index 0000000..f704bcf
Binary files /dev/null and b/01.Linux基础/09.存储管理/机械硬盘hdd.png differ
diff --git a/01.Linux基础/09.存储管理/磁盘容量配额1.png b/01.Linux基础/09.存储管理/磁盘容量配额1.png
new file mode 100644
index 0000000..28d07ab
Binary files /dev/null and b/01.Linux基础/09.存储管理/磁盘容量配额1.png differ
diff --git a/01.Linux基础/09.存储管理/虚拟文件接口.png b/01.Linux基础/09.存储管理/虚拟文件接口.png
new file mode 100644
index 0000000..f856e3a
Binary files /dev/null and b/01.Linux基础/09.存储管理/虚拟文件接口.png differ
diff --git a/01.Linux基础/09.存储管理/设备命名规则.png b/01.Linux基础/09.存储管理/设备命名规则.png
new file mode 100644
index 0000000..e57e23d
Binary files /dev/null and b/01.Linux基础/09.存储管理/设备命名规则.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID.md b/01.Linux基础/10.磁盘阵列RAID.md
new file mode 100644
index 0000000..353c345
--- /dev/null
+++ b/01.Linux基础/10.磁盘阵列RAID.md
@@ -0,0 +1,883 @@
+# 1. 磁盘阵列
+
+磁盘阵列(RAID,**R**edundant **A**rray of **I**ndependent **D**isks)是一种将多个物理硬盘组合在一起形成一个逻辑硬盘组的技术。通过 RAID,可以实现数据冗余、性能提升或两者兼具。RAID 在存储系统中广泛使用,尤其是在服务器和大数据存储环境中,用于提升数据可靠性和性能。
+
+## 1.1 **RAID 0(条带化,Striping)**
+
+- **特点**: 将数据分块并在多个磁盘上并行存储,提升读写性能。
+- **优点**: 极大提高了读写速度,因为数据在多个磁盘上并行操作。
+- **缺点**: 没有冗余,任何一个磁盘的损坏都会导致整个 RAID 失效,数据丢失。
+- **适用场景**: 需要高性能、数据安全性需求不高的场景,比如视频编辑、临时数据存储等。
+
+
+
+## 1.2 **RAID 1(镜像,Mirroring)**
+
+- **特点**: 将数据完全复制到另一块磁盘上,提供 1:1 的数据冗余。
+- **优点**: 数据安全性高,任何一个磁盘损坏时,数据仍可以从镜像磁盘中恢复。
+- **缺点**: 存储效率较低,实际可用存储空间为所有磁盘容量的一半。
+- **适用场景**: 需要高数据可靠性和快速恢复的场合,比如数据库、操作系统磁盘等。
+
+
+
+## 1.3 **RAID 5(带奇偶校验的条带化,Striping with Parity)**
+
+- **特点**: 将数据和奇偶校验数据分布在所有磁盘上,提供冗余的同时提升性能。
+- **优点**: 提供数据冗余,同时存储效率较高(磁盘数量越多,效率越好),能够在一个磁盘损坏的情况下恢复数据。
+- **缺点**: 写入性能稍差,尤其是在发生设备故障时,重建过程较慢。
+- **适用场景**: 需要兼顾性能和数据冗余的场景,如文件服务器和应用服务器。
+
+- 写性能*1,读性能\*(N-1)
+
+RAID5的核心思想是使用奇偶校验信息来提供数据的冗余备份。当其中一个硬盘驱动器发生故障时,剩余的硬盘驱动器可以通过计算奇偶校验信息来恢复丢失的数据。这种方式既提供了数据冗余和容错能力,又降低了整体存储成本。
+
+
+
+## 1.4 **RAID 10(RAID 1+0,镜像与条带化的组合)**
+
+- **特点**: 将 RAID 1(镜像)和 RAID 0(条带化)结合使用,既提供数据冗余又提升了性能。
+- **优点**: 既有 RAID 0 的高性能,又有 RAID 1 的高安全性。能够快速恢复数据。
+- **缺点**: 存储效率较低,要求至少 4 块磁盘,实际可用空间为所有磁盘容量的一半。
+- **适用场景**: 需要高性能和高冗余的关键应用场景,如数据库、虚拟化环境等。
+
+- 读写性能*N(N为RAID0的硬盘数,此例为2),不能同时坏数据块1a与2a
+
+
+
+## 1.5 **硬件磁盘阵列(Hardware RAID)**
+
+### 1.5.1 **特点**
+
+- **专用硬件控制器**:硬件 RAID 使用专门的 RAID 控制器卡(RAID Controller),通常是插入主板的 PCIe 扩展卡或者集成在服务器主板上的芯片。该控制器管理磁盘阵列的所有操作并执行 RAID 级别的计算。
+- **独立于操作系统**:硬件 RAID 完全独立于操作系统,RAID 控制器负责所有 RAID 相关操作,操作系统只看到一个逻辑磁盘。
+- **硬件加速**:硬件 RAID 卡通常带有专用处理器(ASIC 或 FPGA)和缓存,用来加速 RAID 操作,提高性能
+
+### 1.5.2 阵列卡
+
+
+
+## 1.6 **软件磁盘阵列(Software RAID)**
+
+### 1.6.1 **特点**
+
+- **由操作系统实现**:软件 RAID 通过操作系统内核或专门的 RAID 软件来管理和实现 RAID 功能。Linux 的 `mdadm`、Windows 的动态磁盘管理和 macOS 的磁盘工具等都支持软件 RAID。
+- **没有专用硬件**:软件 RAID 不需要专用的 RAID 控制器,所有 RAID 计算和管理工作都由主机的 CPU 执行。
+- **灵活性高**:软件 RAID 通常可以在不同的硬件平台之间迁移,因为 RAID 配置数据存储在磁盘上,而不是特定的控制器中。
+
+## 1.7 **硬件 RAID 和软件 RAID 的对比**
+
+| **对比项** | **硬件 RAID** | **软件 RAID** |
+| ------------ | ---------------------------------------- | ---------------------------------- |
+| **实现方式** | 专用 RAID 控制器 | 操作系统或软件实现 |
+| **性能** | 高,特别是在 RAID 5/6 等级别中 | 较低,占用主机 CPU 资源 |
+| **磁盘管理** | 独立于操作系统,系统只看到一个逻辑磁盘 | 依赖于操作系统的磁盘管理 |
+| **成本** | 高,需购买 RAID 控制器 | 低,无需额外硬件 |
+| **功能支持** | 支持热备盘、硬盘监控、电池缓存等高级功能 | 功能较少,依赖操作系统提供的功能 |
+| **灵活性** | 依赖特定硬件,不易迁移 | 容易迁移,跨硬件平台使用 |
+| **故障恢复** | 控制器损坏可能需要相同型号的控制器 | 可以在不同硬件上恢复 |
+| **适用场景** | 企业级、大型存储系统,数据中心 | 个人用户、小型服务器,开发测试环境 |
+
+# 2. 部署磁盘阵列
+
+为了后续实验,我们先添加5块全新的磁盘。关机状态下,在虚拟机设置中新增磁盘即可。最好添加完成以后,拍个快照保存一下。方便我们后续多次实验恢复。
+
+
+
+## 2.1 mdadm磁盘整列
+
+对于Linux上通过软件的形式构建磁盘整列,我们常用的方式是通过mdadm这个工具来完成。当然对于部分Linux发行版本,mdadm可能没有内置安装好,所以我们需要手动安装一下。
+
+## 2.2 安装mdadm工具
+
+yum是Linux中用于安装软件的工具,可以理解为应用商店
+
+```sh
+[root@localhost ~]# yum -y install mdadm
+```
+
+## 2.3 mdadm命令
+
+常用参数以及作用
+
+| 参数 | 作用 |
+| ---- | ---------------- |
+| -a | 检测设备名称 |
+| -n | 指定设备数量 |
+| -l | 指定RAID级别 |
+| -C | 创建 |
+| -v | 显示过程 |
+| -f | 模拟设备损坏 |
+| -r | 移除设备 |
+| -Q | 查看摘要信息 |
+| -D | 查看详细信息 |
+| -S | 停止RAID磁盘阵列 |
+| -x | 备份盘数量 |
+
+## 2.4 RAID 0阵列实验
+
+### 2.4.1 部署
+
+1. 创建RAID 0阵列
+
+```sh
+[root@localhost ~]# mdadm -Cv /dev/md0 -a yes -n 2 -l 0 /dev/nvme0n2 /dev/nvme0n3
+mdadm: chunk size defaults to 512K
+mdadm: Defaulting to version 1.2 metadata
+mdadm: array /dev/md0 started.
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─md0 9:0 0 10G 0 raid0
+nvme0n3 259:4 0 5G 0 disk
+└─md0 9:0 0 10G 0 raid0
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+```
+
+通过lsblk命令检查RAID 0阵列创建情况
+
+2. 格式化文件系统
+
+```sh
+[root@localhost ~]# mkfs.ext4 /dev/md0
+mke2fs 1.46.5 (30-Dec-2021)
+/dev/md0 contains a ext4 file system
+ last mounted on Wed Nov 13 15:48:49 2024
+Proceed anyway? (y,N) y
+Creating filesystem with 2618880 4k blocks and 655360 inodes
+Filesystem UUID: 8d1dcad6-2788-40db-8dbd-55b5b7105dbc
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+```
+
+3. 创建挂载点,并对设备进行挂载
+
+```sh
+[root@localhost ~]# mkdir /mnt/RAID0
+[root@localhost ~]# mount /dev/md0 /mnt/RAID0
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 24K 9.3G 1% /mnt/RAID0
+
+# mount为临时挂载,也可以将挂载信息写入/etc/fstab文件中,进行永久挂载
+[root@localhost ~]# echo "/dev/md0 /mnt/RAID0 ext4 defaults 0 0" >> /etc/fstab
+[root@localhost ~]# mount -a
+mount: (hint) your fstab has been modified, but systemd still uses
+ the old version; use 'systemctl daemon-reload' to reload.
+[root@localhost ~]# systemctl daemon-reload
+[root@localhost ~]# mount -a
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 24K 9.3G 1% /mnt/RAID0
+
+# 确保fstab文件中的内容格式正确
+```
+
+4. 查看/dev/md0磁盘阵列的详细信息
+
+```sh
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Nov 14 16:10:58 2024
+ Raid Level : raid0
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Update Time : Thu Nov 14 16:10:58 2024
+ State : clean
+ Active Devices : 2
+ Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Layout : original
+ Chunk Size : 512K
+
+Consistency Policy : none
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 25a30480:323ceeda:d3d95a78:0f5321f7
+ Events : 0
+
+ Number Major Minor RaidDevice State
+ 0 259 3 0 active sync /dev/nvme0n2
+ 1 259 4 1 active sync /dev/nvme0n3
+```
+
+**部分字段解释:**
+
+**Number**: 这个字段表示每个磁盘在 RAID 阵列中的编号(从 0 开始)。这是 RAID 阵列中每个设备的索引或设备号。
+
+**Major**: 这是设备文件的主设备号(major number),它用于标识设备的类型。不同的主设备号通常对应不同的驱动程序或设备类别。
+
+**Minor**: 这是设备文件的次设备号(minor number),用于标识同一类型设备中的不同实例。主设备号和次设备号共同唯一标识系统中的一个设备。
+
+**RaidDevice**: 这是设备在 RAID 阵列中的逻辑设备编号。通常从 0 开始,表示该设备在 RAID 阵列中的顺序。
+
+**State**: 表示 RAID 阵列中该设备的当前状态。常见状态如下:
+
+- **active sync**: 表示该设备处于活动状态,并且与 RAID 阵列中的其他设备同步。
+- **faulty**: 表示设备出现故障,不能正常工作。
+- **spare**: 表示该设备是热备盘,当其他设备故障时可自动替换。
+
+**set-A / set-B**: 这可能是与 RAID 10 或其他多组 RAID 配置相关的信息,表示该磁盘属于某个 RAID 子组或镜像组。例如,**set-A** 和 **set-B** 可能表示 RAID 10 配置中的两个镜像组。
+
+**/dev/nvme0nX**: 这是设备的名称,表示设备在系统中的路径。在这里,设备是 NVMe 协议的磁盘(例如,`/dev/nvme0n2`)。不同的数字后缀(例如 `n2`, `n3` 等)表示不同的 NVMe 设备。
+
+### 2.4.2 测试
+
+通过fio磁盘测试工具来测试我们的RAID 0阵列的读写情况
+
+```sh
+[root@localhost ~]# yum install -y fio
+```
+
+#### 2.4.2.1 单块硬盘测试
+
+```sh
+# 先挂载单块硬盘
+[root@localhost ~]# mkdir /mnt/test
+[root@localhost ~]# mkfs.ext4 /dev/nvme0n4
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 1310720 4k blocks and 327680 inodes
+Filesystem UUID: 0694e52f-3816-4223-b51b-6600bf32bb21
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# mount /dev/nvme0n4 /mnt/test
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 24K 9.3G 1% /mnt/RAID0
+/dev/nvme0n4 4.9G 24K 4.6G 1% /mnt/test
+
+# 开始测试
+[root@localhost test]# fio --name=write_test --filename=/mnt/test/testfile --size=1G --bs=1M --rw=write --direct=1 --numjobs=1
+write_test: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, i oengine=psync, iodepth=1
+fio-3.35
+Starting 1 process
+write_test: Laying out IO file (1 file / 1024MiB)
+
+write_test: (groupid=0, jobs=1): err= 0: pid=29670: Thu Nov 14 16:51:32 2024
+ write: IOPS=1404, BW=1405MiB/s (1473MB/s)(1024MiB/729msec); 0 zone resets
+ clat (usec): min=570, max=2700, avg=694.62, stdev=136.39
+ lat (usec): min=588, max=2709, avg=710.02, stdev=136.41
+ clat percentiles (usec):
+ | 1.00th=[ 586], 5.00th=[ 594], 10.00th=[ 603], 20.00th=[ 619],
+ | 30.00th=[ 635], 40.00th=[ 652], 50.00th=[ 668], 60.00th=[ 693],
+ | 70.00th=[ 709], 80.00th=[ 742], 90.00th=[ 783], 95.00th=[ 848],
+ | 99.00th=[ 1057], 99.50th=[ 1450], 99.90th=[ 2409], 99.95th=[ 2704],
+ | 99.99th=[ 2704]
+ bw ( MiB/s): min= 1400, max= 1400, per=99.67%, avg=1400.00, stdev= 0.00, samples=1
+ iops : min= 1400, max= 1400, avg=1400.00, stdev= 0.00, samples=1
+ lat (usec) : 750=83.11%, 1000=15.53%
+ lat (msec) : 2=1.07%, 4=0.29%
+ cpu : usr=0.14%, sys=8.52%, ctx=1024, majf=0, minf=8
+ IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
+ submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ issued rwts: total=0,1024,0,0 short=0,0,0,0 dropped=0,0,0,0
+ latency : target=0, window=0, percentile=100.00%, depth=1
+
+Run status group 0 (all jobs):
+ WRITE: bw=1405MiB/s (1473MB/s), 1405MiB/s-1405MiB/s (1473MB/s-1473MB/s), io=1024MiB (1074MB), run=729-729msec
+
+Disk stats (read/write):
+ nvme0n4: ios=0/1793, merge=0/6, ticks=0/1173, in_queue=1173, util=86.50%
+```
+
+#### 2.4.2.2 RAID 0测试
+
+```sh
+[root@localhost RAID0]# fio --name=write_test --filename=/mnt/RAID0/testfile --size=1G --bs=1M --rw=write --d irect=1 --numjobs=1
+write_test: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=psync , iodepth=1
+fio-3.35
+Starting 1 process
+write_test: Laying out IO file (1 file / 1024MiB)
+
+write_test: (groupid=0, jobs=1): err= 0: pid=29232: Thu Nov 14 16:40:26 2024
+ write: IOPS=1314, BW=1315MiB/s (1378MB/s)(1024MiB/779msec); 0 zone resets
+ clat (usec): min=513, max=3382, avg=737.41, stdev=259.09
+ lat (usec): min=527, max=3469, avg=759.04, stdev=265.36
+ clat percentiles (usec):
+ | 1.00th=[ 537], 5.00th=[ 570], 10.00th=[ 578], 20.00th=[ 611],
+ | 30.00th=[ 627], 40.00th=[ 660], 50.00th=[ 676], 60.00th=[ 709],
+ | 70.00th=[ 758], 80.00th=[ 824], 90.00th=[ 898], 95.00th=[ 963],
+ | 99.00th=[ 2147], 99.50th=[ 2540], 99.90th=[ 3294], 99.95th=[ 3392],
+ | 99.99th=[ 3392]
+ bw ( MiB/s): min= 1275, max= 1275, per=97.03%, avg=1275.45, stdev= 0.00, samples=1
+ iops : min= 1275, max= 1275, avg=1275.00, stdev= 0.00, samples=1
+ lat (usec) : 750=69.43%, 1000=26.86%
+ lat (msec) : 2=2.34%, 4=1.37%
+ cpu : usr=0.39%, sys=9.77%, ctx=1024, majf=0, minf=10
+ IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
+ submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ issued rwts: total=0,1024,0,0 short=0,0,0,0 dropped=0,0,0,0
+ latency : target=0, window=0, percentile=100.00%, depth=1
+
+Run status group 0 (all jobs):
+ WRITE: bw=1315MiB/s (1378MB/s), 1315MiB/s-1315MiB/s (1378MB/s-1378MB/s), io=1024MiB (1074MB), run=779-779ms ec
+
+Disk stats (read/write):
+ md0: ios=0/1660, merge=0/0, ticks=0/1229, in_queue=1229, util=86.06%, aggrios=0/1024, aggrmerge=0/0, aggr ticks=0/703, aggrin_queue=703, aggrutil=86.57%
+ nvme0n2: ios=0/1024, merge=0/0, ticks=0/702, in_queue=702, util=86.57%
+ nvme0n3: ios=0/1024, merge=0/0, ticks=0/705, in_queue=705, util=86.57%
+```
+
+由此可以看出,似乎单块磁盘和RAID 0的写入速度是差不多一样的。按道理来说,RAID 0是将数据分散在两块磁盘上,写入速度理应翻倍。但是由于这是虚拟机,使用我们自己电脑的物理磁盘,我们的物理硬盘只有一块,所以这里看不到RAID 0的双倍读写速度的效果。
+
+### 2.4.3 删除磁盘阵列
+
+```sh
+# 先取消挂载,如果写入到fstab文件中,要记得删除
+[root@localhost ~]# umount /dev/md0
+# 停止磁盘整列
+[root@localhost ~]# mdadm -S /dev/md0
+mdadm: stopped /dev/md0
+# 删除阵列中的数据块信息
+[root@localhost ~]# mdadm --zero-superblock /dev/nvme0n2 /dev/nvme0n3
+# 检查磁盘情况
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+nvme0n3 259:4 0 5G 0 disk
+nvme0n4 259:5 0 5G 0 disk /mnt/test
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+```
+
+## 2.5 RAID 1阵列实验
+
+### 2.5.1 部署
+
+按照上面实验中的方式,创建RAID1阵列以及完成挂载
+
+```bash
+[root@localhost ~]# mdadm -Cv /dev/md0 -a yes -n 2 -l 1 /dev/nvme0n2 /dev/nvme0n3
+mdadm: Note: this array has metadata at the start and
+ may not be suitable as a boot device. If you plan to
+ store '/boot' on this device please ensure that
+ your boot-loader understands md/v1.x metadata, or use
+ --metadata=0.90
+mdadm: size set to 5237760K
+Continue creating array? y
+mdadm: Defaulting to version 1.2 metadata
+mdadm: array /dev/md0 started.
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─md0 9:0 0 5G 0 raid1
+nvme0n3 259:4 0 5G 0 disk
+└─md0 9:0 0 5G 0 raid1
+nvme0n4 259:5 0 5G 0 disk /mnt/test
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+[root@localhost ~]# mkfs.ext4 /dev/md0
+mke2fs 1.46.5 (30-Dec-2021)
+/dev/md0 contains a ext4 file system
+ last mounted on /mnt/RAID0 on Thu Nov 14 16:39:48 2024
+Proceed anyway? (y,N) y
+Creating filesystem with 1309440 4k blocks and 327680 inodes
+Filesystem UUID: fa3601df-6ddb-4471-afcc-fbf501a8e891
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# mkdir /mnt/RAID1
+[root@localhost ~]# mount /dev/md0 /mnt/RAID1
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/nvme0n4 4.9G 1.1G 3.6G 22% /mnt/test
+/dev/md0 4.9G 24K 4.6G 1% /mnt/RAID1
+```
+
+**注意最后的磁盘大小,我们将使用两块大小为5G的磁盘创建RAID1阵列。但是发现最后的磁盘大小还是5G,这也验证了RAID 1的特性,两块磁盘存放一样的数据,将数据镜像化,所以可用空间也会打对折**
+
+### 2.5.2 磁盘写入测试
+
+```sh
+[root@localhost ~]# fio --name=write_test --filename=/mnt/RAID1/testfile --size=1G --bs=1M --rw=write --direct=1 --numjobs=1
+write_test: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=psync, iodepth=1
+fio-3.35
+Starting 1 process
+write_test: Laying out IO file (1 file / 1024MiB)
+Jobs: 1 (f=1)
+write_test: (groupid=0, jobs=1): err= 0: pid=29656: Thu Nov 14 16:48:10 2024
+ write: IOPS=726, BW=727MiB/s (762MB/s)(1024MiB/1409msec); 0 zone resets
+ clat (usec): min=1057, max=6693, avg=1349.52, stdev=401.77
+ lat (usec): min=1074, max=6748, avg=1372.68, stdev=404.55
+ clat percentiles (usec):
+ | 1.00th=[ 1090], 5.00th=[ 1156], 10.00th=[ 1172], 20.00th=[ 1205],
+ | 30.00th=[ 1221], 40.00th=[ 1237], 50.00th=[ 1270], 60.00th=[ 1303],
+ | 70.00th=[ 1336], 80.00th=[ 1385], 90.00th=[ 1500], 95.00th=[ 1713],
+ | 99.00th=[ 3097], 99.50th=[ 3884], 99.90th=[ 5866], 99.95th=[ 6718],
+ | 99.99th=[ 6718]
+ bw ( KiB/s): min=716800, max=763904, per=99.48%, avg=740352.00, stdev=33307.56, samples=2
+ iops : min= 700, max= 746, avg=723.00, stdev=32.53, samples=2
+ lat (msec) : 2=96.58%, 4=2.93%, 10=0.49%
+ cpu : usr=0.36%, sys=7.53%, ctx=1031, majf=0, minf=9
+ IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
+ submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ issued rwts: total=0,1024,0,0 short=0,0,0,0 dropped=0,0,0,0
+ latency : target=0, window=0, percentile=100.00%, depth=1
+
+Run status group 0 (all jobs):
+ WRITE: bw=727MiB/s (762MB/s), 727MiB/s-727MiB/s (762MB/s-762MB/s), io=1024MiB (1074MB), run=1409-1409msec
+
+Disk stats (read/write):
+ md0: ios=0/2009, merge=0/0, ticks=0/2531, in_queue=2531, util=92.94%, aggrios=0/2050, aggrmerge=0/0, aggrticks=0/2499, aggrin_queue=2500, aggrutil=91.91%
+ nvme0n2: ios=0/2050, merge=0/0, ticks=0/2476, in_queue=2477, util=91.91%
+ nvme0n3: ios=0/2050, merge=0/0, ticks=0/2522, in_queue=2523, util=91.91%
+```
+
+从测试结果中可以看见,RAID 1阵列的磁盘写入速度会比单块磁盘相对慢一点,因为RAID 1阵列是将一份数据写入两遍。
+
+## 2.6 RAID 10阵列实验
+
+建议恢复快照到磁盘刚添加磁盘的状态。最少需要4块额外的硬盘
+
+### 2.6.1 部署
+
+1. 创建RAID 10阵列
+
+```sh
+[root@localhost ~]# mdadm -Cv /dev/md0 -a yes -n 4 -l 10 /dev/nvme0n2 /dev/nvme0n3 /dev/nvme0n4 /dev/nvme0n5
+mdadm: layout defaults to n2
+mdadm: layout defaults to n2
+mdadm: chunk size defaults to 512K
+mdadm: size set to 5237760K
+mdadm: Defaulting to version 1.2 metadata
+mdadm: array /dev/md0 started.
+[root@localhost ~]# mkfs.ext4 /dev/md0
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 2618880 4k blocks and 655360 inodes
+Filesystem UUID: bd12aabd-52c7-41c3-81b8-bfb89a8ee580
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# mkdir /mnt/RAID10
+[root@localhost ~]# mount /dev/md0 /mnt/RAID10
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 24K 9.3G 1% /mnt/RAID10
+# 这里可以看到,虽然我们使用了4块大小为5G的硬盘,但是最后的实际大小只有10G。
+```
+
+2. 检查整列情况
+
+```sh
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Nov 14 17:07:34 2024
+ Raid Level : raid10
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 4
+ Total Devices : 4
+ Persistence : Superblock is persistent
+
+ Update Time : Thu Nov 14 17:21:26 2024
+ State : clean
+ Active Devices : 4
+ Working Devices : 4
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Layout : near=2
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 7011a5e6:862c3556:6bbba92b:8a61ce4e
+ Events : 17
+
+ Number Major Minor RaidDevice State
+ 0 259 3 0 active sync set-A /dev/nvme0n2
+ 1 259 4 1 active sync set-B /dev/nvme0n3
+ 2 259 5 2 active sync set-A /dev/nvme0n4
+ 3 259 6 3 active sync set-B /dev/nvme0n5
+```
+
+### 2.6.2 磁盘写入测试
+
+```sh
+[root@localhost RAID10]# fio --name=write_test --filename=/mnt/RAID10/testfile --size=1G --bs=1M --rw=write --direct=1 --numjobs=1
+write_test: (g=0): rw=write, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=psync, iodepth=1
+fio-3.35
+Starting 1 process
+write_test: Laying out IO file (1 file / 1024MiB)
+Jobs: 1 (f=1)
+write_test: (groupid=0, jobs=1): err= 0: pid=27150: Thu Nov 14 17:29:34 2024
+ write: IOPS=715, BW=715MiB/s (750MB/s)(1024MiB/1432msec); 0 zone resets
+ clat (usec): min=1122, max=5646, avg=1373.87, stdev=264.26
+ lat (usec): min=1140, max=5741, avg=1395.28, stdev=266.74
+ clat percentiles (usec):
+ | 1.00th=[ 1156], 5.00th=[ 1205], 10.00th=[ 1221], 20.00th=[ 1254],
+ | 30.00th=[ 1287], 40.00th=[ 1303], 50.00th=[ 1336], 60.00th=[ 1369],
+ | 70.00th=[ 1401], 80.00th=[ 1450], 90.00th=[ 1516], 95.00th=[ 1614],
+ | 99.00th=[ 2040], 99.50th=[ 2606], 99.90th=[ 5669], 99.95th=[ 5669],
+ | 99.99th=[ 5669]
+ bw ( KiB/s): min=733184, max=737852, per=100.00%, avg=735518.00, stdev=3300.77, samples=2
+ iops : min= 716, max= 720, avg=718.00, stdev= 2.83, samples=2
+ lat (msec) : 2=98.73%, 4=1.07%, 10=0.20%
+ cpu : usr=0.49%, sys=6.57%, ctx=1026, majf=0, minf=10
+ IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
+ submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
+ issued rwts: total=0,1024,0,0 short=0,0,0,0 dropped=0,0,0,0
+ latency : target=0, window=0, percentile=100.00%, depth=1
+
+Run status group 0 (all jobs):
+ WRITE: bw=715MiB/s (750MB/s), 715MiB/s-715MiB/s (750MB/s-750MB/s), io=1024MiB (1074MB), run=1432-1432msec
+
+Disk stats (read/write):
+ md0: ios=0/1984, merge=0/0, ticks=0/2554, in_queue=2554, util=93.47%, aggrios=0/1024, aggrmerge=0/0, aggrticks=0/1284, aggrin_queue=1284, aggrutil=92.57%
+ nvme0n4: ios=0/1024, merge=0/0, ticks=0/1272, in_queue=1272, util=92.31%
+ nvme0n2: ios=0/1024, merge=0/0, ticks=0/1277, in_queue=1278, util=92.31%
+ nvme0n5: ios=0/1024, merge=0/0, ticks=0/1312, in_queue=1312, util=92.57%
+ nvme0n3: ios=0/1024, merge=0/0, ticks=0/1277, in_queue=1277, util=92.31%
+
+```
+
+### 2.6.3 损坏磁盘阵列及修复
+
+在确认有一块物理硬盘设备出现损坏而不能继续正常使用后,应该使用mdadm命令将其移除,然后查看RAID磁盘阵列的状态,可以发现状态已经改变。
+
+```bash
+[root@localhost RAID10]# mdadm /dev/md0 -f /dev/nvme0n2
+mdadm: set /dev/nvme0n2 faulty in /dev/md0
+[root@localhost RAID10]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Nov 14 17:07:34 2024
+ Raid Level : raid10
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 4
+ Total Devices : 4
+ Persistence : Superblock is persistent
+
+ Update Time : Fri Nov 15 10:05:55 2024
+ State : clean, degraded
+ Active Devices : 3
+ Working Devices : 3
+ Failed Devices : 1
+ Spare Devices : 0
+
+ Layout : near=2
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 7011a5e6:862c3556:6bbba92b:8a61ce4e
+ Events : 19
+
+ Number Major Minor RaidDevice State
+ - 0 0 0 removed
+ 1 259 4 1 active sync set-B /dev/nvme0n3
+ 2 259 5 2 active sync set-A /dev/nvme0n4
+ 3 259 6 3 active sync set-B /dev/nvme0n5
+
+ 0 259 3 - faulty /dev/nvme0n2
+```
+
+在RAID 10级别的磁盘阵列中,当RAID 1磁盘阵列中存在一个故障盘时并不影响RAID 10磁盘阵列的使用。当购买了新的硬盘设备后再使用mdadm命令来予以替换即可,在此期间我们可以在/RAID目录中正常地创建或删除文件。由于我们是在虚拟机中模拟硬盘,所以先重启系统,然后再把新的硬盘添加到RAID磁盘阵列中。
+
+```bash
+[root@localhost ~]# umount /mnt/RAID10
+#有时候失败,告诉设备忙,-f参数都没用
+#可以使用fuser -mk /mnt/RAID10命令杀死所有占用该文件的进程
+
+# 先热移除/dev/nvme0n2
+[root@localhost ~]# mdadm /dev/md0 -r /dev/nvme0n2
+mdadm: hot removed /dev/nvme0n2 from /dev/md0
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Nov 14 17:07:34 2024
+ Raid Level : raid10
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 4
+ Total Devices : 3
+ Persistence : Superblock is persistent
+
+ Update Time : Fri Nov 15 10:09:16 2024
+ State : clean, degraded
+ Active Devices : 3
+ Working Devices : 3
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Layout : near=2
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 7011a5e6:862c3556:6bbba92b:8a61ce4e
+ Events : 22
+
+ Number Major Minor RaidDevice State
+ - 0 0 0 removed
+ 1 259 4 1 active sync set-B /dev/nvme0n3
+ 2 259 5 2 active sync set-A /dev/nvme0n4
+ 3 259 6 3 active sync set-B /dev/nvme0n5
+# 再重新添加/dev/nvme0n2
+[root@localhost ~]# mdadm /dev/md0 -a /dev/nvme0n2
+mdadm: added /dev/nvme0n2
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Nov 14 17:07:34 2024
+ Raid Level : raid10
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 4
+ Total Devices : 4
+ Persistence : Superblock is persistent
+
+ Update Time : Fri Nov 15 10:10:25 2024
+ State : clean, degraded, recovering
+ Active Devices : 3
+ Working Devices : 4
+ Failed Devices : 0
+ Spare Devices : 1
+
+ Layout : near=2
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Rebuild Status : 31% complete
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 7011a5e6:862c3556:6bbba92b:8a61ce4e
+ Events : 28
+
+ Number Major Minor RaidDevice State
+ 4 259 3 0 spare rebuilding /dev/nvme0n2
+ 1 259 4 1 active sync set-B /dev/nvme0n3
+ 2 259 5 2 active sync set-A /dev/nvme0n4
+ 3 259 6 3 active sync set-B /dev/nvme0n5
+# 会发现,刚添加上的磁盘处于rebuilding的状态,等待一会儿,就会恢复正常了。
+
+# 重新再次挂载即可正常使用
+[root@localhost ~]# mount /dev/md0 /mnt/RAID10/
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 1.1G 8.3G 11% /mnt/RAID10
+
+# 有的时候,可能会存在/dev/nvme0n2无法添加的情况,对于这种情况,只能将整个整列全部删除干净之后重新创建
+```
+
+## 2.7 RAID 5阵列实验+备份盘
+
+为了避免多个实验之间相互发生冲突,我们需要保证每个实验的相对独立性,为此需要大家自行将虚拟机还原到初始状态。
+
+部署RAID 5磁盘阵列时,至少需要用到3块硬盘,还需要再加一块备份硬盘,所以总计需要在虚拟机中模拟4块硬盘设备
+
+
+现在创建一个RAID 5磁盘阵列+备份盘。在下面的命令中,参数-n 3代表创建这个RAID 5磁盘阵列所需的硬盘数,参数-l 5代表RAID的级别,而参数-x 1则代表有一块备份盘。当查看/dev/md0(即RAID 5磁盘阵列的名称)磁盘阵列的时候就能看到有一块备份盘在等待中了。
+
+```bash
+[root@localhost ~]# mdadm -Cv /dev/md0 -n 3 -l 5 -x 1 /dev/nvme0n2 /dev/nvme0n3 /dev/nvme0n4 /dev/nvme0n5
+mdadm: layout defaults to left-symmetric
+mdadm: layout defaults to left-symmetric
+mdadm: chunk size defaults to 512K
+mdadm: size set to 5237760K
+mdadm: Defaulting to version 1.2 metadata
+mdadm: array /dev/md0 started.
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Fri Nov 15 10:33:07 2024
+ Raid Level : raid5
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 3
+ Total Devices : 4
+ Persistence : Superblock is persistent
+
+ Update Time : Fri Nov 15 10:33:33 2024
+ State : clean
+ Active Devices : 3
+ Working Devices : 4
+ Failed Devices : 0
+ Spare Devices : 1
+
+ Layout : left-symmetric
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 8f9130a4:06668353:958e7628:985d1167
+ Events : 18
+
+ Number Major Minor RaidDevice State
+ 0 259 3 0 active sync /dev/nvme0n2
+ 1 259 4 1 active sync /dev/nvme0n3
+ 4 259 5 2 active sync /dev/nvme0n4
+
+ 3 259 6 - spare /dev/nvme0n5
+```
+
+将部署好的RAID 5磁盘阵列格式化为ext4文件格式,然后挂载到目录上,之后就可以使用了。
+
+```bash
+[root@localhost ~]# mkfs.ext4 /dev/md0
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 2618880 4k blocks and 655360 inodes
+Filesystem UUID: 33c5ee4e-82de-4c0f-98f1-88cda85292ea
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (16384 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# mkdir /mnt/RAID5
+[root@localhost ~]# echo "/dev/md0 /mnt/RAID5 ext4 defaults 0 0" >> /etc/fstab
+[root@localhost ~]# mount -a
+mount: (hint) your fstab has been modified, but systemd still uses
+ the old version; use 'systemctl daemon-reload' to reload.
+[root@localhost ~]# systemctl daemon-reload
+[root@localhost ~]# mount -a
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 6.3M 343M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/md0 9.8G 24K 9.3G 1% /mnt/RAID5
+
+```
+
+把硬盘设备/dev/nvme0n2移出磁盘阵列,然后迅速查看/dev/md0磁盘阵列的状态
+
+```bash
+[root@localhost ~]# mdadm /dev/md0 -f /dev/nvme0n2
+mdadm: set /dev/nvme0n2 faulty in /dev/md0
+# /dev/nvme0n5由原来的spare顶上来变成spare-building
+[root@localhost ~]# mdadm -D /dev/md0
+/dev/md0:
+ Version : 1.2
+ Creation Time : Fri Nov 15 10:33:07 2024
+ Raid Level : raid5
+ Array Size : 10475520 (9.99 GiB 10.73 GB)
+ Used Dev Size : 5237760 (5.00 GiB 5.36 GB)
+ Raid Devices : 3
+ Total Devices : 4
+ Persistence : Superblock is persistent
+
+ Update Time : Fri Nov 15 10:41:21 2024
+ State : clean, degraded, recovering
+ Active Devices : 2
+ Working Devices : 3
+ Failed Devices : 1
+ Spare Devices : 1
+
+ Layout : left-symmetric
+ Chunk Size : 512K
+
+Consistency Policy : resync
+
+ Rebuild Status : 11% complete
+
+ Name : localhost.localdomain:0 (local to host localhost.localdomain)
+ UUID : 8f9130a4:06668353:958e7628:985d1167
+ Events : 21
+
+ Number Major Minor RaidDevice State
+ 3 259 6 0 spare rebuilding /dev/nvme0n5
+ 1 259 4 1 active sync /dev/nvme0n3
+ 4 259 5 2 active sync /dev/nvme0n4
+
+ 0 259 3 - faulty /dev/nvme0n2
+# 然后过一会儿,/dev/nvme0n5的状态就会变成active sync
+```
\ No newline at end of file
diff --git a/01.Linux基础/10.磁盘阵列RAID/RAID0.png b/01.Linux基础/10.磁盘阵列RAID/RAID0.png
new file mode 100644
index 0000000..4de929f
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/RAID0.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID/RAID1.png b/01.Linux基础/10.磁盘阵列RAID/RAID1.png
new file mode 100644
index 0000000..9cabdce
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/RAID1.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID/RAID10.png b/01.Linux基础/10.磁盘阵列RAID/RAID10.png
new file mode 100644
index 0000000..83ae8d1
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/RAID10.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID/RAID5.png b/01.Linux基础/10.磁盘阵列RAID/RAID5.png
new file mode 100644
index 0000000..9cc9f3e
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/RAID5.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID/部署磁盘阵列.png b/01.Linux基础/10.磁盘阵列RAID/部署磁盘阵列.png
new file mode 100644
index 0000000..f5812e1
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/部署磁盘阵列.png differ
diff --git a/01.Linux基础/10.磁盘阵列RAID/阵列卡.png b/01.Linux基础/10.磁盘阵列RAID/阵列卡.png
new file mode 100644
index 0000000..5cd4d7b
Binary files /dev/null and b/01.Linux基础/10.磁盘阵列RAID/阵列卡.png differ
diff --git a/01.Linux基础/11.LVM逻辑卷管理.md b/01.Linux基础/11.LVM逻辑卷管理.md
new file mode 100644
index 0000000..e7bdf6e
--- /dev/null
+++ b/01.Linux基础/11.LVM逻辑卷管理.md
@@ -0,0 +1,617 @@
+# 1. LVM(逻辑卷管理器)
+
+逻辑卷管理器是Linux系统用于对硬盘分区进行管理的一种机制,理论性较强,其创建初衷是为了解决硬盘设备在创建分区后不易修改分区大小的缺陷。尽管对传统的硬盘分区进行强制扩容或缩容从理论上来讲是可行的,但是却可能造成数据的丢失。而LVM技术是在硬盘分区和文件系统之间添加了一个逻辑层,它提供了一个抽象的卷组,可以把多块硬盘进行卷组合并。这样一来,用户不必关心物理硬盘设备的底层架构和布局,就可以实现对硬盘分区的动态调整。
+
+
+
+物理卷处于LVM中的最底层,可以将其理解为物理硬盘、硬盘分区或者RAID磁盘阵列,这都可以。卷组建立在物理卷之上,一个卷组可以包含多个物理卷,而且在卷组创建之后也可以继续向其中添加新的物理卷。逻辑卷是用卷组中空闲的资源建立的,并且逻辑卷在建立后可以动态地扩展或缩小空间。这就是LVM的核心理念。
+
+PE最小存储单元,VG通过PV组合好PE,成一个整的;然后LV从VG分出来可供挂载使用
+
+## 1.1 部署逻辑卷
+
+常用的LVM部署命令
+
+| 功能/命令 | 物理卷管理 | 卷组管理 | 逻辑卷管理 |
+| --------- | ---------- | --------- | ---------- |
+| 扫描 | pvscan | vgscan | lvscan |
+| 建立 | pvcreate | vgcreate | lvcreate |
+| 显示 | pvdisplay | vgdisplay | lvdisplay |
+| 删除 | pvremove | vgremove | lvremove |
+| 扩展 | | vgextend | lvextend |
+| 缩小 | | vgreduce | lvreduce |
+
+为了避免多个实验之间相互发生冲突,请大家自行将虚拟机还原到初始状态,并在虚拟机中添加两块新硬盘设备,然后开机
+
+第1步:让新添加的两块硬盘设备支持LVM技术
+
+```bash
+[root@localhost ~]# pvcreate /dev/nvme0n2 /dev/nvme0n3
+ Physical volume "/dev/nvme0n2" successfully created.
+ Physical volume "/dev/nvme0n3" successfully created.
+#有时候创建不成功,有残留数据需要重新做分区表
+#[root@localhost ~]#parted /dev/sd[b-c] mklabel msdos
+```
+
+第2步:把两块硬盘设备加入到storage卷组中,然后查看卷组的状态
+
+```bash
+[root@localhost ~]# vgcreate storage /dev/nvme0n2 /dev/nvme0n3
+ Volume group "storage" successfully created
+[root@localhost ~]# vgdisplay storage
+ --- Volume group ---
+ VG Name storage
+ System ID
+ Format lvm2
+ Metadata Areas 2
+ Metadata Sequence No 1
+ VG Access read/write
+ VG Status resizable
+ MAX LV 0
+ Cur LV 0
+ Open LV 0
+ Max PV 0
+ Cur PV 2
+ Act PV 2
+ VG Size 9.99 GiB
+ PE Size 4.00 MiB
+ Total PE 2558
+ Alloc PE / Size 0 / 0
+ Free PE / Size 2558 / 9.99 GiB
+ VG UUID fhR9kn-q5mT-CxO1-Skst-c5mN-X1nN-TbQpU6
+```
+
+第3步:切割出一个约为150MB的逻辑卷设备。
+
+这里需要注意切割单位的问题。在对逻辑卷进行切割时有两种计量单位。
+
+第一种是以容量为单位,所使用的参数为-L。例如,使用-L 150M生成一个大小为150MB的逻辑卷。
+
+另外一种是以基本单元的个数为单位,所使用的参数为-l。每个基本单元的大小默认为4MB。例如,使用-l 37可以生成一个大小为37×4MB=148MB的逻辑卷。
+
+```bash
+# [root@localhost ~]# lvcreate -n vo -l 37 -I 8M storage
+[root@localhost ~]# lvcreate -n vo -l 37 storage
+ Logical volume "vo" created.
+# 每个PE占4M,37*4=148M,远少于/dev/nvme0n2的5G,不会占用到第二个PV(/dev/nvme0n3),所以lsblk只看到占用了/dev/nvme0n2
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─storage-vo 253:2 0 148M 0 lvm
+nvme0n3 259:4 0 5G 0 disk
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+
+[root@localhost ~]# lvdisplay
+ --- Logical volume ---
+ LV Path /dev/storage/vo
+ LV Name vo
+ VG Name storage
+ LV UUID X83QDm-cgYS-Vlsj-FHqq-pJWh-bWnY-NhoozO
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-16 17:35:36 +0800
+ LV Status available
+ # open 0
+ LV Size 148.00 MiB
+ Current LE 37
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:2
+
+ --- Logical volume ---
+ LV Path /dev/rl/swap
+ LV Name swap
+ VG Name rl
+ LV UUID mStLV7-xYcw-4GHG-vdEC-igob-LNmI-xWVQRF
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 2
+ LV Size 2.00 GiB
+ Current LE 512
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:1
+
+ --- Logical volume ---
+ LV Path /dev/rl/root
+ LV Name root
+ VG Name rl
+ LV UUID yQ6wgx-mgEh-ACiF-Au17-X7Qs-PzQx-0eiqg3
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 1
+ LV Size <17.00 GiB
+ Current LE 4351
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:0
+```
+
+第4步:把生成好的逻辑卷进行格式化,然后挂载使用。
+
+```bash
+[root@localhost ~]# mkfs.ext4 /dev/storage/vo
+mke2fs 1.46.5 (30-Dec-2021)
+Creating filesystem with 151552 1k blocks and 37848 inodes
+Filesystem UUID: 11f83627-21f1-42fb-a19b-6ccfdc62453d
+Superblock backups stored on blocks:
+ 8193, 24577, 40961, 57345, 73729
+
+Allocating group tables: done
+Writing inode tables: done
+Creating journal (4096 blocks): done
+Writing superblocks and filesystem accounting information: done
+
+[root@localhost ~]# mkdir /mnt/vo
+[root@localhost ~]# mount /dev/storage/vo /mnt/vo
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/mapper/storage-vo 134M 14K 123M 1% /mnt/vo
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─storage-vo 253:2 0 148M 0 lvm /mnt/vo
+nvme0n3 259:4 0 5G 0 disk
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+
+[root@localhost ~]# echo "/dev/storage/vo /mnt/vo ext4 defaults 0 0" >> /etc/fstab
+```
+
+## 1.2 扩容逻辑卷
+
+第1步:把上一个实验中的逻辑卷vo扩展至290MB
+
+```bash
+[root@localhost ~]# umount /mnt/vo
+[root@localhost ~]# lvextend -L 290M /dev/storage/vo
+ Rounding size to boundary between physical extents: 292.00 MiB.
+ Size of logical volume storage/vo changed from 148.00 MiB (37 extents) to 292.00 MiB (73 extents).
+ Logical volume storage/vo successfully resized.
+```
+
+第2步:检查硬盘完整性,并重置硬盘容量,否则挂载了还是148M
+
+```bash
+[root@localhost ~]# e2fsck -f /dev/storage/vo
+e2fsck 1.46.5 (30-Dec-2021)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+/dev/storage/vo: 11/37848 files (0.0% non-contiguous), 15165/151552 blocks
+[root@localhost ~]# resize2fs /dev/storage/vo
+resize2fs 1.46.5 (30-Dec-2021)
+Resizing the filesystem on /dev/storage/vo to 299008 (1k) blocks.
+The filesystem on /dev/storage/vo is now 299008 (1k) blocks long.
+```
+
+第3步:重新挂载硬盘设备并查看挂载状态
+
+```bash
+[root@localhost ~]# systemctl daemon-reload
+[root@localhost ~]# mount -a
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/mapper/storage-vo 268M 14K 250M 1% /mnt/vo
+```
+
+第4步,如果扩容到6G,则会占用到nvme0n3的pv
+
+```shell
+[root@localhost ~]# umount /mnt/vo
+[root@localhost ~]# lvextend -L 6G /dev/storage/vo
+ Size of logical volume storage/vo changed from 292.00 MiB (73 extents) to 6.00 GiB (1536 extents).
+ Logical volume storage/vo successfully resized.
+[root@localhost ~]# e2fsck -f /dev/storage/vo
+e2fsck 1.46.5 (30-Dec-2021)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+/dev/storage/vo: 11/73704 files (0.0% non-contiguous), 24683/299008 blocks
+[root@localhost ~]# resize2fs /dev/storage/vo
+resize2fs 1.46.5 (30-Dec-2021)
+Resizing the filesystem on /dev/storage/vo to 6291456 (1k) blocks.
+The filesystem on /dev/storage/vo is now 6291456 (1k) blocks long.
+
+[root@localhost ~]# mount -a
+[root@localhost ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
+sr0 11:0 1 1.7G 0 rom
+nvme0n1 259:0 0 20G 0 disk
+├─nvme0n1p1 259:1 0 1G 0 part /boot
+└─nvme0n1p2 259:2 0 19G 0 part
+ ├─rl-root 253:0 0 17G 0 lvm /
+ └─rl-swap 253:1 0 2G 0 lvm [SWAP]
+nvme0n2 259:3 0 5G 0 disk
+└─storage-vo 253:2 0 6G 0 lvm /mnt/vo
+nvme0n3 259:4 0 5G 0 disk
+└─storage-vo 253:2 0 6G 0 lvm /mnt/vo
+nvme0n4 259:5 0 5G 0 disk
+nvme0n5 259:6 0 5G 0 disk
+nvme0n6 259:7 0 5G 0 disk
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/mapper/storage-vo 5.7G 14K 5.4G 1% /mnt/vo
+```
+
+## 1.3 缩小逻辑卷
+
+第1步:检查文件系统的完整性
+
+```bash
+[root@localhost ~]# umount /mnt/vo
+[root@localhost ~]# e2fsck -f /dev/storage/vo
+e2fsck 1.46.5 (30-Dec-2021)
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+/dev/storage/vo: 11/1529856 files (0.0% non-contiguous), 391996/6291456 blocks
+```
+
+第2步:把逻辑卷vo的容量减小到120MB
+
+```bash
+[root@localhost ~]# resize2fs /dev/storage/vo 120M
+resize2fs 1.46.5 (30-Dec-2021)
+Resizing the filesystem on /dev/storage/vo to 122880 (1k) blocks.
+The filesystem on /dev/storage/vo is now 122880 (1k) blocks long.
+
+[root@localhost ~]# lvreduce -L 120M /dev/storage/vo
+ File system ext4 found on storage/vo.
+ File system size (120.00 MiB) is equal to the requested size (120.00 MiB).
+ File system reduce is not needed, skipping.
+ Size of logical volume storage/vo changed from 6.00 GiB (1536 extents) to 120.00 MiB (30 extents).
+ Logical volume storage/vo successfully resized.
+```
+
+第3步:重新挂载文件系统并查看系统状态
+
+```bash
+[root@localhost ~]# mount -a
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/mapper/storage-vo 108M 14K 99M 1% /mnt/vo
+```
+
+## 1.4 逻辑卷快照
+
+LVM还具备有“快照卷”功能,该功能类似于虚拟机软件的还原时间点功能。例如,可以对某一个逻辑卷设备做一次快照,如果日后发现数据被改错了,就可以利用之前做好的快照卷进行覆盖还原。LVM的快照卷功能有两个特点:
+
+- 快照卷的容量必须等同于逻辑卷的容量;
+- 快照卷仅一次有效,一旦执行还原操作后则会被立即自动删除。
+
+```bash
+[root@localhost ~]# vgdisplay
+ --- Volume group ---
+ VG Name storage
+ System ID
+ Format lvm2
+ Metadata Areas 2
+ Metadata Sequence No 5
+ VG Access read/write
+ VG Status resizable
+ MAX LV 0
+ Cur LV 1
+ Open LV 1
+ Max PV 0
+ Cur PV 2
+ Act PV 2
+ VG Size 9.99 GiB
+ PE Size 4.00 MiB
+ Total PE 2558
+ Alloc PE / Size 30 / 120.00 MiB
+ Free PE / Size 2528 / <9.88 GiB # 容量剩余9.88G
+ VG UUID fhR9kn-q5mT-CxO1-Skst-c5mN-X1nN-TbQpU6
+
+ --- Volume group ---
+ VG Name rl
+ System ID
+ Format lvm2
+ Metadata Areas 1
+ Metadata Sequence No 3
+ VG Access read/write
+ VG Status resizable
+ MAX LV 0
+ Cur LV 2
+ Open LV 2
+ Max PV 0
+ Cur PV 1
+ Act PV 1
+ VG Size <19.00 GiB
+ PE Size 4.00 MiB
+ Total PE 4863
+ Alloc PE / Size 4863 / <19.00 GiB
+ Free PE / Size 0 / 0
+ VG UUID GbAoZ2-IvHg-YKLQ-366L-f2lq-qo71-T79Hm6
+```
+
+接下来用重定向往逻辑卷设备所挂载的目录中写入一个文件
+
+```bash
+[root@localhost ~]# echo "hello world" > /mnt/vo/readme.txt
+[root@localhost ~]# ls -l /mnt/vo
+total 14
+drwx------. 2 root root 12288 Apr 18 13:38 lost+found
+-rw-r--r--. 1 root root 12 Apr 18 13:48 readme.txt
+```
+
+第1步:使用-s参数生成一个快照卷,使用-L参数指定切割的大小。
+
+另外,还需要在命令后面写上是针对哪个逻辑卷执行的快照操作。**强烈建议快照大小和原来的LVM一样大**
+
+```bash
+[root@localhost ~]# lvcreate -L 120M -s -n SNAP /dev/storage/vo
+#强烈建议快照大小和原来的LVM一样大,虽然指定大小是120M,并不是创建一个120M大小的快照,除非修改、新增的文件超出120M才会出事情,删除不影响。
+ Logical volume "SNAP" created.
+[root@localhost ~]# lvdisplay
+ --- Logical volume ---
+ LV Path /dev/storage/vo
+ LV Name vo
+ VG Name storage
+ LV UUID X83QDm-cgYS-Vlsj-FHqq-pJWh-bWnY-NhoozO
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-16 17:35:36 +0800
+ LV snapshot status source of
+ SNAP [active]
+ LV Status available
+ # open 1
+ LV Size 120.00 MiB
+ Current LE 30
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:2
+
+ --- Logical volume ---
+ LV Path /dev/storage/SNAP
+ LV Name SNAP
+ VG Name storage
+ LV UUID om37W1-JVXY-yctX-4Rm7-Bh9L-ERVo-JlqTuV
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-16 17:43:02 +0800
+ LV snapshot status active destination for vo
+ LV Status available
+ # open 0
+ LV Size 120.00 MiB
+ Current LE 30
+ COW-table size 120.00 MiB
+ COW-table LE 30
+ Allocated to snapshot 0.01%
+ Snapshot chunk size 4.00 KiB
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:5
+
+ --- Logical volume ---
+ LV Path /dev/rl/swap
+ LV Name swap
+ VG Name rl
+ LV UUID mStLV7-xYcw-4GHG-vdEC-igob-LNmI-xWVQRF
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 2
+ LV Size 2.00 GiB
+ Current LE 512
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:1
+
+ --- Logical volume ---
+ LV Path /dev/rl/root
+ LV Name root
+ VG Name rl
+ LV UUID yQ6wgx-mgEh-ACiF-Au17-X7Qs-PzQx-0eiqg3
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 1
+ LV Size <17.00 GiB
+ Current LE 4351
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:0
+```
+
+第2步:在逻辑卷所挂载的目录中创建一个50MB的垃圾文件,然后再查看快照卷的状态。可以发现存储空间占的用量上升了
+
+```bash
+[root@localhost ~]# dd if=/dev/zero of=/mnt/vo/files count=1 bs=50M
+1+0 records in
+1+0 records out
+104857600 bytes (105 MB) copied, 3.29409 s, 31.8 MB/s
+[root@localhost ~]# lvdisplay
+ --- Logical volume ---
+ LV Path /dev/storage/vo
+ LV Name vo
+ VG Name storage
+ LV UUID X83QDm-cgYS-Vlsj-FHqq-pJWh-bWnY-NhoozO
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-16 17:35:36 +0800
+ LV snapshot status source of
+ SNAP [active]
+ LV Status available
+ # open 1
+ LV Size 120.00 MiB
+ Current LE 30
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:2
+
+ --- Logical volume ---
+ LV Path /dev/storage/SNAP
+ LV Name SNAP
+ VG Name storage
+ LV UUID om37W1-JVXY-yctX-4Rm7-Bh9L-ERVo-JlqTuV
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-16 17:43:02 +0800
+ LV snapshot status active destination for vo
+ LV Status available
+ # open 0
+ LV Size 120.00 MiB
+ Current LE 30
+ COW-table size 120.00 MiB
+ COW-table LE 30
+ Allocated to snapshot 41.90% # 从0.01变成了41.90
+ Snapshot chunk size 4.00 KiB
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:5
+
+ --- Logical volume ---
+ LV Path /dev/rl/swap
+ LV Name swap
+ VG Name rl
+ LV UUID mStLV7-xYcw-4GHG-vdEC-igob-LNmI-xWVQRF
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 2
+ LV Size 2.00 GiB
+ Current LE 512
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:1
+
+ --- Logical volume ---
+ LV Path /dev/rl/root
+ LV Name root
+ VG Name rl
+ LV UUID yQ6wgx-mgEh-ACiF-Au17-X7Qs-PzQx-0eiqg3
+ LV Write Access read/write
+ LV Creation host, time localhost.localdomain, 2024-11-09 10:51:12 +0800
+ LV Status available
+ # open 1
+ LV Size <17.00 GiB
+ Current LE 4351
+ Segments 1
+ Allocation inherit
+ Read ahead sectors auto
+ - currently set to 8192
+ Block device 253:0
+```
+
+第3步:为了校验SNAP快照卷的效果,需要对逻辑卷进行快照还原操作。在此之前记得先卸载掉逻辑卷设备与目录的挂载。
+
+```bash
+[root@localhost ~]# umount /mnt/vo
+[root@localhost ~]# lvconvert --merge /dev/storage/SNAP
+ Merging of volume storage/SNAP started.
+ storage/vo: Merged: 31.39%
+ storage/vo: Merged: 100.00%
+```
+
+第4步:快照卷会被自动删除掉,并且刚刚在逻辑卷设备被执行快照操作后再创建出来的50MB的垃圾文件也被清除了
+
+```bash
+[root@localhost ~]# mount -a
+[root@localhost ~]# ls /mnt/vo/
+lost+found readme.txt
+```
+
+## 1.5 删除逻辑卷
+
+第1步:取消逻辑卷与目录的挂载关联,删除配置文件中永久生效的设备参数。
+
+```bash
+[root@localhost ~]# umount /mnt/vo/
+[root@localhost ~]# vi /etc/fstab
+#
+# /etc/fstab
+# Created by anaconda on Mon Apr 15 17:31:00 2019
+#
+# Accessible filesystems, by reference, are maintained under '/dev/disk'
+# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
+#
+/dev/mapper/centos-root / xfs defaults 0 0
+UUID=63e91158-e754-41c3-b35d-7b9698e71355 /boot xfs defaults 0 0
+/dev/mapper/centos-swap swap swap defaults 0 0
+```
+
+第2步:删除逻辑卷设备,需要输入y来确认操作
+
+```bash
+[root@localhost ~]# lvremove /dev/storage/vo
+Do you really want to remove active logical volume storage/vo? [y/n]: y
+ Logical volume "vo" successfully removed
+```
+
+第3步:删除卷组,此处只写卷组名称即可,不需要设备的绝对路径。
+
+```bash
+[root@localhost ~]# vgremove storage
+ Volume group "storage" successfully removed
+```
+
+第4步:删除物理卷设备
+
+```bash
+[root@localhost ~]# pvremove /dev/nvme0n2 /dev/nvme0n3
+ Labels on physical volume "/dev/nvme0n2" successfully wiped.
+ Labels on physical volume "/dev/nvme0n3" successfully wiped.
+```
\ No newline at end of file
diff --git a/01.Linux基础/11.LVM逻辑卷管理/LVM逻辑图.png b/01.Linux基础/11.LVM逻辑卷管理/LVM逻辑图.png
new file mode 100644
index 0000000..e560700
Binary files /dev/null and b/01.Linux基础/11.LVM逻辑卷管理/LVM逻辑图.png differ
diff --git a/01.Linux基础/12.软件包管理.md b/01.Linux基础/12.软件包管理.md
new file mode 100644
index 0000000..e029dd7
--- /dev/null
+++ b/01.Linux基础/12.软件包管理.md
@@ -0,0 +1,647 @@
+# 1. 软件包的类型
+
+- 源码包
+ - 需要编译
+- 二进制包
+ - 已编译
+
+常见二进制包类型
+
+- RedHat/Centos
+ - RPM
+ - 工具
+ - rpm
+ - yum(在线安装,自动解决依赖关系)
+ - dnf(yum的升级版本,在RockyLinux中,yum命令是dnf的软连接)
+- Ubuntu/Debain
+ - DPKG
+ - 工具
+ - dpkg
+ - apt(在线安装,自动解决依赖关系)
+
+注意!不管是源码包,还是二进制包,安装时都可能会有依赖关系
+
+# 2. yum/dnf
+
+yum/dnf是红帽系列的发行版本上用来下载和安装软件包的一个工具
+
+我们可以使用`yum install xxx`命令来安装一个软件
+
+但是大家有没有考虑过一个问题?yum工具是去哪里找到这些软件包的呢?
+
+这就不得不提到`yum源`,所谓`源`的意思就是指这些软件包的来源,也可以成称之为`软件仓库`
+
+## 2.1 dnf与yum的对比
+
+**YUM (Yellowdog Updater, Modified)**:
+
+- 是 RHEL 8 及之前版本使用的包管理工具。
+- 提供了一个简单的命令行接口,用来安装、更新、删除和管理 RPM 软件包。
+- 基于 Python 2 开发,在性能和依赖性解析方面存在一定的限制。
+
+**DNF (Dandified YUM)**:
+
+- 是 YUM 的下一代替代工具,首次在 Fedora 18 引入,并从 RHEL 8 开始逐步取代 YUM,到了 RHEL 9 完全淘汰 YUM。
+- 采用了更先进的依赖解析器和更高效的代码。
+- 基于 Python 3 开发,支持现代特性和技术,性能更高。
+
+**RockyLinux中yum命令的本质:**
+
+```sh
+[root@localhost bin]# ll /usr/bin/ | grep dnf
+lrwxrwxrwx. 1 root root 5 Apr 14 2024 dnf -> dnf-3
+-rwxr-xr-x. 1 root root 2094 Apr 14 2024 dnf-3
+lrwxrwxrwx. 1 root root 5 Apr 14 2024 yum -> dnf-3
+```
+
+由此可以看出,yum命令和dnf命令都链接自dnf-3。实际上dnf-3才是包管理器的真正可执行程序,代表基于python3开发。这样链接是为了我们使用起来更方便。
+
+## 2.2 官方源
+
+一些有名的大厂或者高校都有提供他们整合好的`软件仓库`
+
+- 阿里云镜像:[https://mirrors.aliyun.com/rockylinux/](https://mirrors.aliyun.com/rockylinux/)
+- 腾讯云镜像:[https://mirrors.cloud.tencent.com/rocky/](https://mirrors.cloud.tencent.com/rocky/)
+- 中科大镜像:[https://mirrors.ustc.edu.cn/rocky/](https://mirrors.ustc.edu.cn/rocky/)
+- 上海交大镜像:[https://mirrors.sjtug.sjtu.edu.cn/rocky/](https://mirrors.sjtug.sjtu.edu.cn/rocky/)
+- 西安交大镜像:[https://mirrors.xjtu.edu.cn/rocky/](https://mirrors.xjtu.edu.cn/rocky/)
+- 浙江大学镜像:[https://mirrors.zju.edu.cn/rocky/](https://mirrors.zju.edu.cn/rocky/)
+- 南京大学镜像:[https://mirrors.nju.edu.cn/rocky/](https://mirrors.nju.edu.cn/rocky/)
+- 山东大学镜像:[https://mirrors.sdu.edu.cn/rocky/](https://mirrors.sdu.edu.cn/rocky/)
+- 兰州大学镜像:[https://mirror.lzu.edu.cn/rocky/](https://mirror.lzu.edu.cn/rocky/)
+- 大连东软镜像:[https://mirrors.neusoft.edu.cn/rocky/](https://mirrors.neusoft.edu.cn/rocky/)
+
+```bash
+[root@localhost ~]# yum repolist # 查看现有的软件仓库
+repo id repo name
+appstream Rocky Linux 9 - AppStream
+baseos Rocky Linux 9 - BaseOS
+extras Rocky Linux 9 - Extras
+```
+
+软件源相关文件存放的位置`/etc/yum.repos.d/`
+
+```bash
+[root@localhost ~]# ls /etc/yum.repos.d/
+rocky-addons.repo rocky-devel.repo rocky-extras.repo rocky.repo
+
+# 这里面的一个个.repo文件就是一个个软件仓库
+```
+
+可以尝试添加中科大软件仓库,下面的是RockyLinux的添加命令
+
+```bash
+# 备份原来的源
+[root@localhost ~]# mkdir /repobackup
+[root@localhost ~]# cp /etc/yum.repos.d/* /repobackup/
+# 使用sed命令,替换原来repo文件中的内容
+[root@localhost ~]# sed -e 's|^mirrorlist=|#mirrorlist=|g' \
+ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.ustc.edu.cn/rocky|g' \
+ -i.bak \
+ /etc/yum.repos.d/rocky-extras.repo \
+ /etc/yum.repos.d/rocky.repo
+
+# 更新缓存
+[root@localhost ~]# yum makecache
+Rocky Linux 9 - BaseOS 4.1 MB/s | 2.3 MB 00:00
+Rocky Linux 9 - AppStream 9.2 MB/s | 8.3 MB 00:00
+Rocky Linux 9 - Extras 34 kB/s | 15 kB 00:00
+Metadata cache created.
+[root@localhost ~]# yum repolist
+repo id repo name
+appstream Rocky Linux 9 - AppStream
+baseos Rocky Linux 9 - BaseOS
+extras Rocky Linux 9 - Extras
+```
+
+- EPEL源(Extra Packages for Enterprise Linux)为“红帽系”的操作系统提供额外的软件包
+ - `yum -y install epel-release`
+
+## 2.3 yum常用命令
+
+### 2.3.1 **查看当前可用仓库**
+
+```bash
+[root@localhost ~]# yum clean all # 清空缓存及其他文件
+[root@localhost ~]# yum makecache # 重建缓存
+[root@localhost ~]# yum repolist # 查询可用的仓库
+```
+
+### 2.3.2 **查找软件包**
+
+注意:有些命令跟软件包的名字是不同的
+
+```bash
+1. 通过命令的名字查找是属于哪个软件包
+[root@localhost ~]# yum provides pstree
+Last metadata expiration check: 0:00:20 ago on Fri Nov 22 14:50:43 2024.
+psmisc-23.4-3.el9.x86_64 : Utilities for managing processes on your system
+Repo : @System
+Matched from:
+Filename : /usr/bin/pstree
+
+psmisc-23.4-3.el9.x86_64 : Utilities for managing processes on your system
+Repo : baseos
+Matched from:
+Filename : /usr/bin/pstree
+
+2. 通过配置文件查找属于哪个软件包提供的
+[root@localhost ~]# yum provides /etc/ssh/sshd_config
+Last metadata expiration check: 0:00:56 ago on Fri Nov 22 14:50:43 2024.
+openssh-server-8.7p1-38.el9.x86_64 : An open source SSH server daemon
+Repo : @System
+Matched from:
+Filename : /etc/ssh/sshd_config
+
+openssh-server-8.7p1-43.el9.x86_64 : An open source SSH server daemon
+Repo : baseos
+Matched from:
+Filename : /etc/ssh/sshd_config
+
+3. 通过search参数查找软件包
+[root@localhost ~]# yum search psmisc
+Last metadata expiration check: 0:02:07 ago on Fri Nov 22 14:50:43 2024.
+======================================= Name Exactly Matched: psmisc ========================================
+psmisc.x86_64 : Utilities for managing processes on your system
+
+4. 查看系统中的安装包
+[root@localhost ~]# yum list installed # 查看已安装的所有软件包
+[root@localhost ~]# yum list # 查看所有可以安装的软件包
+[root@localhost ~]# yum list httpd
+```
+
+### 2.3.3 **安装软件包**
+
+```bash
+# yum install xxx
+
+- 安装httpd软件包
+[root@localhost ~]# yum install -y httpd
+-y:一律允许
+[root@localhost ~]# yum install -y httpd vim nginx # 多个软件包之间用空格隔开
+[root@localhost ~]# yum reinstall httpd # 重新安装
+[root@localhost ~]# yum update httpd # 更新软件包的版本-laster
+[root@localhost ~]# yum update # 更新所有软件包到软件仓库的最新版本
+
+# 从本地安装
+[root@localhost ~]# yum install -y httpd-2.4.57-11.el9_4.x86_64.rpm
+Last metadata expiration check: 0:06:47 ago on Fri Nov 22 14:50:43 2024.
+Error:
+ Problem: conflicting requests
+ - nothing provides httpd-core = 2.4.57-11.el9_4 needed by httpd-2.4.57-11.el9_4.x86_64 from @commandline
+(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
+
+# 从URL安装
+[root@localhost ~]# yum install -y https://rpmfind.net/linux/almalinux/9.4/AppStream/x86_64/os/Packages/httpd-2.4.57-11.el9_4.x86_64.rpm
+Last metadata expiration check: 0:07:55 ago on Fri Nov 22 14:50:43 2024.
+httpd-2.4.57-11.el9_4.x86_64.rpm 27 kB/s | 45 kB 00:01
+Error:
+ Problem: conflicting requests
+ - nothing provides httpd-core = 2.4.57-11.el9_4 needed by httpd-2.4.57-11.el9_4.x86_64 from @commandline
+(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
+```
+
+### 2.3.4 管理软件包组
+
+软件包组就是把一些相关的软件包给整合起来,可以打包安装和卸载
+
+```sh
+[root@localhost ~]# export LANG="en-US.utf8" 切换英文环境
+[root@localhost ~]# yum grouplist
+Failed to set locale, defaulting to C.UTF-8
+Last metadata expiration check: 0:08:59 ago on Fri Nov 22 14:50:43 2024.
+Available Environment Groups:
+ Server with GUI
+ Server
+ Workstation
+ KDE Plasma Workspaces
+ Custom Operating System
+ Virtualization Host
+Installed Environment Groups:
+ Minimal Install
+Available Groups:
+ Fedora Packager
+ VideoLAN Client
+ Xfce
+ Legacy UNIX Compatibility
+ Console Internet Tools
+ Container Management
+ Development Tools
+ .NET Development
+ Graphical Administration Tools
+ Headless Management
+ Network Servers
+ RPM Development Tools
+ Scientific Support
+ Security Tools
+ Smart Card Support
+ System Tools
+
+[root@localhost ~]# yum groupinfo "Server with GUI"
+[root@localhost ~]# yum groupinstall "Server with GUI"
+[root@localhost ~]# yum -y groupremove "Server with GUI"
+```
+
+#### 2.3.4.1 切换图形化模式
+
+- 临时切换到图形化模式
+
+```python
+[root@localhost ~]# systemctl isolate graphical.target
+```
+
+- 永久切换(开机进入图形化)
+
+```sh
+[root@localhost ~]# systemctl set-default graphical.target
+
+# 验证启动模式
+[root@localhost ~]# systemctl get-default
+multi-user.target
+```
+
+- 临时切换到命令行模式
+
+```sh
+[root@localhost ~]# systemctl isolate multi-user.target
+```
+
+- 永久切换
+
+```sh
+[root@localhost ~]# systemctl set-default multi-user.target
+```
+
+#### 2.3.4.2 **软件包组解释**
+
+##### 2.3.4.2.1 **Environment Groups(环境组)**
+
+- **Server with GUI**
+ GNOME 桌面环境及相关应用
+- **Server**
+ 无图形界面的纯服务器环境,包含基本的服务器组件(SSH、存储管理、网络管理工具等)
+- **Workstation**
+ 桌面工作站环境,适合普通用户和开发人员,包含办公软件、多媒体支持和开发工具
+- **KDE Plasma Workspaces**
+ KDE Plasma 桌面环境及其相关工具
+- **Custom Operating System**
+ 自定义操作系统环境,用户可以手动选择需要的软件包
+- **Virtualization Host**
+ 专用于虚拟化的环境,包含 KVM、`libvirt` 和虚拟化管理工具
+- **Minimal Install**
+ 最小化安装,仅包含基础系统和命令行工具
+
+------
+
+##### 2.3.4.2.2 **Available Groups(可用的软件包组)**
+
+- **Fedora Packager**
+ 用于构建 Fedora 或 RHEL/CentOS 软件包的工具(如 `rpmdevtools` 和 `mock`)
+- **VideoLAN Client**
+ VLC 媒体播放器及其依赖项
+- **Xfce**
+ 轻量级桌面环境,适合资源受限的设备或低性能机器
+- **Legacy UNIX Compatibility**
+ 提供传统 UNIX 系统兼容的工具和库(如 `csh` 和 `compat-libstdc++`)
+- **Console Internet Tools**
+ 基于命令行的互联网工具(如 `wget`、`curl` 和文本浏览器 `lynx`)
+- **Container Management**
+ 用于管理容器的工具(如 Podman 或 Docker)
+- **Development Tools**
+ 常用开发工具(如 `gcc` 编译器、`gdb` 调试器和 `git` 版本控制工具)
+- **.NET Development**
+ 用于开发和运行 .NET 应用程序的工具和运行时
+- **Graphical Administration Tools**
+ 图形化的系统管理工具(如磁盘管理和网络配置工具)
+- **Headless Management**
+ 用于远程管理无图形界面服务器的工具
+- **Network Servers**
+ 常见网络服务(如 `httpd`、`vsftpd` 和 `bind`)
+- **RPM Development Tools**
+ 用于构建和维护 RPM 软件包的工具(如 `rpmbuild` 和 `createrepo`)
+- **Scientific Support**
+ 科学计算工具和库(如 `numpy` 和 `scipy`)
+- **Security Tools**
+ 安全扫描、入侵检测和分析工具(如 `nmap`、`wireshark` 和 `clamav`)
+- **Smart Card Support**
+ 与智能卡相关的工具和库,支持基于智能卡的身份认证
+- **System Tools**
+ 常用的系统管理工具(如磁盘管理和日志分析工具)
+
+### 2.3.5 **卸载**
+
+```bash
+[root@localhost ~]# yum -y remove httpd # 卸载httpd软件包
+[root@localhost ~]# yum -y groupremove "Server with GUI" # 卸载软件包组
+```
+
+### 2.3.6 **历史记录**
+
+用来查看 yum 软件包管理器的历史记录的
+
+```bash
+[root@localhost ~]# yum history
+[root@localhost ~]# yum history info 4 # 查看具体某个yum记录的信息
+```
+
+## 2.4 yum自建源
+
+除了使用上述提到的官方源之外,我们也可以自己搭建一个自建源用来为系统提供软件仓库
+
+### 2.4.1 实验一:本地yum镜像仓库
+
+可以通过安装系统时下载的iso中的软件包来提供本地软件仓库
+
+RockyLinux ISO下载地址:https://dl.rockylinux.org/vault/rocky/9.4/isos/x86_64/Rocky-9.4-x86_64-dvd.iso
+
+iso文件中具有一些基础的软件包
+
+```bash
+- 挂载本地ISO光盘:
+[root@localhost ~]# ls
+Rocky-9.4-x86_64-dvd.iso anaconda-ks.cfg
+[root@localhost ~]# mkdir /media/cdrom
+[root@localhost ~]# mount Rocky-9.4-x86_64-dvd.iso /media/cdrom/
+mount: /media/cdrom: WARNING: source write-protected, mounted read-only.
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 12G 5.1G 71% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+/dev/loop0 11G 11G 0 100% /media/cdrom
+
+- 清空原有的软件仓库
+[root@localhost ~]# rm -f /etc/yum.repos.d/*
+
+- 配置本地yum
+[root@localhost ~]# vim /etc/yum.repos.d/local.repo
+[BaseOS]
+name=RockyLinux 9.4 BaseOS
+baseurl=file:///media/cdrom/BaseOS
+enabled=1
+gpgcheck=0
+
+[AppStream]
+name=RockyLinux 9.4 AppStream
+baseurl=file:///media/cdrom/AppStream
+enabled=1
+gpgcheck=0
+
+=======================字段解释=========================
+-name 软件仓库名字
+-baseurl 软件包的存放的地址
+-enabled 是否启用这个仓库
+-gpgcheck 是否校验软件包
+
+# 安装软件验证
+[root@localhost cdrom]# yum install -y httpd
+```
+
+### 2.4.2 实验二:提供内网服务器软件包更新
+
+一台server1服务器可以访问公网,一台server2服务器无法访问公网
+
+我们可以在这台能够访问公网的服务器上下载好软件包,通过http或者ftp提供给内网中的server2机器安装软件包
+
+**server1:**
+
+第一步:下载软件包,可以使用`--downloadonly`选项仅下载不安装
+
+第二步:将软件包放到合适的位置上,并且创建软件索引数据
+
+```bash
+[root@localhost ~]# yum clean all # 清理缓存
+[root@localhost ~]# yum update -y --downloadonly --downloaddir=/packages # 仅下载更新包
+[root@localhost ~]# ls /packages/ # 查看下载的包
+
+[root@localhost ~]# mkdir /var/ftp/update
+[root@localhost ~]# find /packages -iname "*.rpm" -exec cp -rf {} /var/ftp/update/ \;
+[root@localhost ~]# yum -y install createrepo # createrepo用来创建软件包的索引
+[root@localhost ~]# createrepo /var/ftp/update/ # 创建软件包的索引
+```
+
+第三步:部署ftp文件服务器,将软件包通过ftp协议共享给sever2
+
+```bash
+# 部署ftp服务并且启动
+[root@localhost ~]# yum -y install vsftpd
+[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf # 更改ftp的配置文件,允许匿名登录
+anonymous_enable=yes
+
+[root@localhost ~]# systemctl start vsftpd
+
+# 关闭防火墙和selinux
+[root@localhost ~]# systemctl stop firewalld
+[root@localhost ~]# setenforce 0
+```
+
+**server2:**
+
+在server2上我们编写repo文件,软件的来源是有server1通过ftp服务提供
+
+```bash
+[root@localhost ~]# rm -rf /etc/yum.repos.d/*.repo #干掉所有的仓库
+[root@localhost ~]# vi /etc/yum.repos.d/update.repo
+[update]
+name=RockyLinux update
+baseurl=ftp://192.168.88.104/update
+gpgcheck=0
+enabled=1
+
+# 关闭防火墙和selinux
+[root@localhost ~]# systemctl stop firewalld
+[root@localhost ~]# setenforce 0
+
+[root@localhost ~]# yum clean all
+[root@localhost ~]# yum update -y # 更新测试
+```
+
+# 3. RPM
+
+在RHEL系列的系统上所使用的软件包为rpm包,上面使用的yum为在线安装软件包。除了在线的安装方法,我们还可以将rpm包下载到本地,然后使用rpm工具来安装这个软件包
+
+- rpm工具使用分为安装、查询、验证、更新、删除等操作
+- rpm包的格式说明:
+
+```bash
+[root@atopos ~]# rpm -ivh httpd-2.4.6-93.el7.centos.x86_64.rpm
+- httpd:包名
+- 2:主版本号
+- 4:次版本号
+- 6:修订次数,指的是第几次修改bug
+- 93:release(第几次发布,指的是简单的修改参数)
+- e17:操作系统版本
+- x86_64:64位操作系统
+```
+
+- 命令格式
+
+```bash
+[root@atopos ~]# rpm [选项] 软件包
+```
+
+## 3.1 选项
+
+**安装:**
+
+- -i:install的意思,安装软件包
+- -v:显示附加信息,提供更多详细信息
+- -V:校验,对已安装的软件进行校验
+
+**查询:**
+
+- -q:查询,一般跟下面的参数配合使用
+- -a:查询所有已安装的软件包
+- -f:系统文件名(查询系统文件属于哪个安装包)
+- -i:显示已安装的rpm软件包信息
+- -l:查询软件包文件的安装位置
+- -p:查询未安装软件包的相关信息
+- -R:查询软件包的依赖性
+
+**卸载:**
+
+- -e:erase
+- --nodeps:忽略依赖
+
+**升级:**
+
+- -U:一般配合vh使用
+
+
+
+## 3.2 实例:安装
+
+```bash
+[root@localhost ~]# rpm -ivh https://rpmfind.net/linux/almalinux/9.4/AppStream/x86_64/os/Packages/httpd-2.4.57-11.el9_4.x86_64.rpm
+
+# 或者
+[root@localhost ~]# wget https://rpmfind.net/linux/almalinux/9.4/AppStream/x86_64/os/Packages/httpd-2.4.57-11.el9_4.x86_64.rpm
+[root@localhost ~]# rpm -ivh httpd-2.4.57-11.el9_4.x86_64.rpm
+错误:依赖检测失败:
+ /etc/mime.types 被 httpd-2.4.6-95.el7.centos.x86_64 需要
+ httpd-tools = 2.4.6-95.el7.centos 被 httpd-2.4.6-95.el7.centos.x86_64 需要
+ libapr-1.so.0()(64bit) 被 httpd-2.4.6-95.el7.centos.x86_64 需要
+ libaprutil-1.so.0()(64bit) 被 httpd-2.4.6-95.el7.centos.x86_64 需要
+
+# 需要自己手动解决依赖关系
+
+# 额外安装选项
+# --nosignature 不检验软件包的签名
+# --force 强制安装软件包
+# --nodeps 忽略依赖关系
+```
+
+## 3.3 实例:查询
+
+```bash
+[root@atopos ~]# rpm -q vim-enhanced
+vim-enhanced-7.4.629-8.el7_9.x86_64
+[root@atopos ~]# rpm -qa |grep vim-enhanced
+vim-enhanced-7.4.629-8.el7_9.x86_64
+[root@atopos ~]# rpm -ql vim-enhanced
+/etc/profile.d/vim.csh
+/etc/profile.d/vim.sh
+/usr/bin/rvim
+/usr/bin/vim
+/usr/bin/vimdiff
+/usr/bin/vimtutor
+[root@atopos ~]# rpm -qc openssh-server
+/etc/pam.d/sshd
+/etc/ssh/sshd_config
+/etc/sysconfig/sshd
+[root@atopos ~]#
+```
+
+## 3.4 实例:卸载
+
+```bash
+[root@atopos ~]# rpm -e vim-enhanced
+```
+
+# 4. 源码包管理
+
+源码包获得途径:
+
+- 官方网站
+ - apache: www.apache.org
+ - nginx: www.nginx.org
+
+- github
+ - www.github.com
+
+编译源码包所需要的环境
+
+这取决于源码所使用的编程语言和框架等,但是Linux基础软件包一般都是由C语言编写的,所以我们使用较多的编译环境为`gcc`、`make`等等
+
+`yum install -y ncurses* gcc gcc-c++ make`
+
+## 4.1 编译
+
+源码包编译三部曲
+
+```bash
+- 第一步:
+./configure
+#可以指定安装路径,启用或者禁用功能等,最终生成makefile
+
+- 第二步
+make
+#按Makefile文件编译。可以加 -j 2 参数使用两个cpu核心进行编译
+
+- 第三步
+make install
+#按Makefile定义的文件路径安装
+
+make clean
+#清除上一次make命令所产生的object文件,要重新执行
+configure时,需要执行make clean。
+```
+
+
+
+## 4.2 案例:编译炫酷代码雨
+
+### 4.2.1 补充:压缩与解压缩
+
+**打包一个文件或者目录**:
+
+```bash
+tar -cvf archive.tar /path/to/directory
+
+-c 表示创建一个新的归档文件。
+-v 表示在压缩过程中显示详细信息(verbose 详细模式)。
+-f 指定归档文件的名称。
+
+# 如果要创建gzip压缩包
+tar -zcvf archive.tar.gz /path/to/directory
+```
+
+**解压缩:**
+
+```bash
+tar -xvf archive.tar
+
+-x 表示解压缩。
+-v 表示显示详细信息。
+-f 指定要解压缩的归档文件。
+
+# 如果归档文件是使用 gzip 压缩的,比如 archive.tar.gz,则需要添加 -z 选项:
+
+tar -zxvf archive.tar.gz
+```
+
+### 4.2.2 开始编译
+
+```bash
+[root@localhost ~]# yum -y install ncurses* gcc gcc-c++
+[root@localhost ~]# tar -zxvf cmatrix-1.2a.tar.gz
+[root@localhost ~]# cd cmatrix-1.2a
+[root@localhost cmatrix-1.2a]# ./configure
+[root@localhost cmatrix-1.2a]# make
+[root@localhost cmatrix-1.2a]# make install
+[root@localhost cmatrix-1.2a]# cmatrix
+```
+
diff --git a/01.Linux基础/13.网络管理.md b/01.Linux基础/13.网络管理.md
new file mode 100644
index 0000000..b2747d8
--- /dev/null
+++ b/01.Linux基础/13.网络管理.md
@@ -0,0 +1,409 @@
+# 1. 数据通信基础
+
+- 数据从产生到传递到目的地的过程中会经历好几个过程,每个过程都负责加工自己这部分的内容,类似于工厂流水线
+- 目前我们只需要有个最基本的概念:
+ - IP地址是用来标识网络中位置的,比如你在江苏省xxx市xxx路xxx号
+ - MAC地址是每个网络设备的唯一ID,比如你的身份证号码
+ - 如果想要发送数据,必须(暂且认为必须)同时拥有IP和MAC地址
+ - Linux的网络管理基础部分就是需要大家掌握IP地址的配置
+
+
+
+## 1.1 IP地址
+
+- 在IP网络中,通信节点需要有一个唯一的IP地址
+- IP地址用于IP报文的寻址以及标识一个节点
+- IPv4地址一共32bits,使用点分十进制的形式表示
+
+
+
+- IPv4地址由网络位和主机位组成
+ - 网络位一致表示在同一个广播域中,可以直接通信
+ - 主机位用于在同一个局域网中标识唯一节点
+
+### 1.1.1 早期IP地址的划分
+
+
+
+- 早期参与互联网的设备不多,所以仅仅使用ABC类地址分配给用户即可
+- 随着网络用户的增多,ABC类分配地址过于浪费,于是出现子网掩码方式划分网络位和主机位
+
+### 1.1.2 IP网络通信类型
+
+- 单播(Unicast)
+- 广播(Broadcast)
+- 组播(Multicast)
+
+### 1.1.3 子网掩码(Netmask)
+
+- 网络掩码与IP地址搭配使用,用于描述一个IP地址中的网络部分及主机部分
+- 网络掩码32bits,与32bits的IP地址一一对应,掩码中为1的位对应IP地址中的网络位,掩码中为0的位对应IP地址中的主机位
+
+
+
+- 减少一个局域网中的设备数量可以有效降低广播报文消耗资源
+
+- 可变长子网掩码可以将一个局域网中的主机地址分配的更加小
+
+
+
+### 1.1.4 广播地址与网络号
+
+- 在局域网中经常会有广播的需要(比如,mac地址查询,地址冲突检测等等),所以将主机位全为1的地址做为本局域网的广播地址(注意!广播并不能跨越不同的局域网)
+- 在网络中需要表示整个局域网,就像邮政编码表示一个大的区域一样,所以将主机位全为0的地址作为本局域网的网络号,用来代指整个网段
+- 综上所述,计算产生的子网及每个子网的主机数量公式如下:
+
+
+
+### 1.1.5 私有IP地址
+
+- 如果要取得互联网合法地址用于通信,必须要找 iana.org 组织分配
+- 很多企业内部都有大量的网络设备,大多数时候这些设备只需要内部通信即可
+- 企业的网络管理员可以从如下网段中自行分配地址
+
+
+
+- 私有IP地址空间中的地址不需要申请,随意使用,但是不能在互联网上与合法地址通信(因为对方没法回复你这个地址,因为世界上私有IP地址段无数个重复的,怎么知道回到谁那里呢)
+- 而我们明明用的私有IP地址,也可以上网,因为我们需要先把自己的上网请求提交给网络中的网关(就是你家的出口路由器),再由网关代替我们去获取内容转交给我们的电脑手机,而网关往往能从运营商那里得到一个合法的公有IP地址
+
+# 2. DHCP
+
+DHCP(动态主机配置协议),主要用于给设备自动的分配IP地址以及网络信息,以便网络设备能够连接到网络并进行通信
+
+DHCP给设备提供的信息如下:
+
+- IP地址
+- 子网掩码
+- 网关地址
+- DNS服务器地址
+- 租约时间
+
+
+
+## 2.1 DHCP工作过程
+
+1. 客户端启动时发送 DHCP 发现(DHCPDISCOVER)广播消息,寻找 DHCP 服务器。
+2. DHCP 服务器收到广播消息后,会提供一个未被使用的 IP 地址以及其他网络配置信息(如子网掩码、默认网关、DNS 服务器等),并发送 DHCP 提供(DHCPOFFER)消息给客户端。
+3. 客户端收到一个或多个 DHCP 提供消息后,会选择其中一个 DHCP 服务器提供的 IP 地址,并发送 DHCP 请求(DHCPREQUEST)消息确认。
+4. DHCP 服务器收到客户端的 DHCP 请求消息后,会将该 IP 地址分配给客户端,并发送 DHCP 确认(DHCPACK)消息给客户端。
+5. 客户端收到 DHCP 确认消息后,就可以使用分配到的 IP 地址和其他网络配置参数连接到网络了。
+
+`dhclient`
+
+我们可以通过抓包软件,捕捉到主机通过DHCP方式获取ip的过程,一共有4个数据包:
+
+
+
+其中每个数据包的作用如下:
+
+1. `Discover`消息是用于客户端向整个内网发送广播,期待DHCP服务器进行回应
+ 1. 这个数据包中的重要内容就是:消息类型,客户端ID,主机名,请求获得的信息
+2. `Offer`消息是DHCP服务器对客户的回应
+ 1. 这个消息中会回复对方所需要的所有信息
+3. `Request`这个是客户端确认DHCP服务器的消息
+ 1. 这个消息和第一个消息差不多,但是消息类别变为`Request`,并且会携带请求的IP地址
+4. `ACK`DHCP服务器给客户端的最终确认
+ 1. 这个消息和第二个消息差不多,但是消息类型变为`ACK`
+
+## 2.2 DHCP续租
+
+DHCP分配的信息是有有效期的,再租约时间快到的时候,如果我们想要继续使用这个地址信息,就需要向DHCP服务器续租
+
+这也是大家虚拟机上IP地址经常发生变化的原因,这是因为虚拟机上默认就是以DHCP的方式获得IP地址的
+
+我们可以查看Linux上的网络配置信息,该信息位于`/etc/NetworkManager/system-connections/ens160.nmconnection`
+
+```bash
+[root@localhost ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection
+[connection]
+id=ens160
+uuid=dfea55d8-6ddc-3229-8152-cb9e261de181
+type=ethernet
+autoconnect-priority=-999
+interface-name=ens160
+timestamp=1731149277
+
+[ethernet]
+
+[ipv4]
+method=auto
+
+[ipv6]
+addr-gen-mode=eui64
+method=auto
+
+[proxy]
+
+
+# 可以看到配置中的method字段是以dhcp来获得IP地址的。
+```
+
+同样从VMware的虚拟网络设置中,也可以看到租约时间相关的内容
+
+
+
+
+
+# 3. DNS(域名解析)
+
+DNS(Domain Name System) 是一套从域名到IP的映射的协议
+
+在网络世界中,如果我们想要给某个机器,或者是某个网站去发送一个数据,都需要通过IP地址来找到对方,比如我们想要使用百度来搜索东西,就需要知道百度的IP地址,换句话说只要知道了百度的IP地址,我们就可以访问到百度
+
+但是IP地址不易记忆,不可能记住每一个网站的IP地址是什么,于是早期的搞IT的那帮人研发出一个叫做主机名的东西。
+
+最开始人们把IP和主机名的的对应关系记录在本地,这个文件目前在windows系统的`C:\Windows\System32\drivers\etc\hosts`中。但是后面发现并不好用,而且需要经常手动更新这个文件。类似于黄历
+
+
+
+随着主机名越来越多,hosts文件不易维护,所以后来改用**域名解析系统DNS**:
+
+- 一个组织的系统管理机构,维护系统内的每个主机的`IP和主机名`的对应关系
+- 如果新计算机接入网络,将这个信息注册到`数据库`中
+- 用户输入域名的时候,会自动查询`DNS`服务器,由`DNS服务器`检索数据库, 得到对应的IP地址。
+
+## 3.1 域名
+
+主域名是用来识别主机名称和主机所属的组织机构的一种分层结构的名称。
+例如:http://www.baidu.com(域名使用.连接)
+
+- com: 一级域名,表示这是一个企业域名。同级的还有 "net"(网络提供商),"org"(非盈利组织) 等。
+- baidu: 二级域名, 公司名。
+- www: 只是一种习惯用法,并不是每个域名都支持。
+- http:// : 要使用什么协议来连接这个主机名。
+
+## 3.2 常见的域名解析服务器
+
+- 114dns
+
+ 114.114.114.114
+
+ 114.114.115.115
+
+ 这是国内用户量数一数二的 dns 服务器,该 dns 一直标榜高速、稳定、无劫持、防钓鱼。
+
+- Google DNS
+
+ 8.8.8.8
+
+ 8.8.4.4
+
+ ......
+
+可以理解为由这些服务器帮我们记录的域名和IP的对应关系,我们访问域名的时候去找这些dns服务器询问该域名对应的IP地址,当然,除了上述提到的这些dns服务器,三大运营商也提供了dns解析服务
+
+## 3.3 域名解析的过程
+
+1. 浏览器发起域名解析,首先查询浏览器缓存,如果没有,就查询hosts文件,如果没有就提出域名解析请求
+2. 客户机提出域名解析请求,并将该请求发送给本地的域名服务器。
+3. 当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。
+4. 如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址。
+5. 本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
+6. 重复第四步,直到找到正确的纪录。
+7. 本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时还将结果返回给客户机
+
+
+
+# 4. 配置网络服务
+
+## 4.1 修改网卡配置文件
+
+```bash
+# 修改网卡配置文件
+[root@localhost ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection
+[connection]
+id=ens160
+uuid=dfea55d8-6ddc-3229-8152-cb9e261de181
+type=ethernet
+autoconnect-priority=-999
+interface-name=ens160
+timestamp=1732264040
+
+[ethernet]
+
+[ipv4]
+address1=192.168.88.110/24,192.168.88.2
+dns=114.114.114.114;114.114.115.115;
+method=manual
+
+[ipv6]
+addr-gen-mode=eui64
+method=auto
+
+[proxy]
+```
+
+当修改完Linux系统中的服务配置文件后,并不会对服务程序立即产生效果。要想让服务程序获取到最新的配置文件,需要手动重启相应的服务,之后就可以看到网络畅通了
+
+```bash
+[root@localhost ~]# systemctl restart NetworkManager
+[root@localhost ~]# ping -c 4 www.baidu.com
+PING www.a.shifen.com (180.101.50.242) 56(84) bytes of data.
+64 bytes from 180.101.50.242 (180.101.50.242): icmp_seq=1 ttl=128 time=11.3 ms
+...
+```
+
+## 4.2 网卡配置文件参数
+
+| **节** | **参数** | **描述** |
+| -------------- | ---------------------- | ------------------------------------------------------------ |
+| `[connection]` | `id` | 连接的名称,这里是 `ens160`。 |
+| | `uuid` | 连接的唯一标识符(UUID),用于唯一识别此连接。 |
+| | `type` | 连接的类型,`ethernet` 表示这是一个以太网连接。 |
+| | `autoconnect-priority` | 自动连接优先级,数值越小优先级越低。这里设置为 `-999`,表示极低的优先级。 |
+| | `interface-name` | 连接对应的网络接口名称,这里是 `ens160`。 |
+| | `timestamp` | 连接的时间戳,表示最后修改的时间。 |
+| `[ethernet]` | - | 此节用于配置以太网特定的设置,当前没有额外参数。 |
+| `[ipv4]` | `address1` | 静态 IPv4 地址及其子网掩码,格式为 `IP地址/子网掩码` 和网关,例:`192.168.88.110/24,192.168.88.2`。 |
+| | `dns` | DNS 服务器地址,多个地址用分号分隔,这里是 `114.114.114.114;114.114.115.115;`。 |
+| | `method` | IPv4 地址配置方法,这里设置为 `manual`,表示使用手动配置。 |
+| `[ipv6]` | `addr-gen-mode` | 地址生成模式,`eui64` 表示使用 EUI-64 地址生成方式。 |
+| | `method` | IPv6 地址配置方法,这里设置为 `auto`,表示自动获取 IPv6 地址。 |
+| `[proxy]` | - | 此节用于配置代理设置,当前没有额外参数。 |
+
+## 4.3 nmcli 工具
+
+nmcli命令是redhat7或者centos7之后的命令,该命令可以完成网卡上所有的配置工作,并且可以写入 配置文件,永久生效
+
+- 查看接口状态
+
+```bash
+[root@localhost ~]# nmcli device status
+DEVICE TYPE STATE CONNECTION
+ens160 ethernet connected ens160
+lo loopback connected (externally) lo
+```
+
+- 查看链接信息
+
+```bash
+[root@localhost ~]# nmcli connection show
+NAME UUID TYPE DEVICE
+ens160 dfea55d8-6ddc-3229-8152-cb9e261de181 ethernet ens160
+lo 529b2eed-2755-4cce-af3c-999beb49882d loopback lo
+```
+
+- 配置IP等网络信息
+
+```bash
+[root@localhost ~]# nmcli con mod "ens160" ipv4.addresses 192.168.88.140/24 ipv4.gateway 192.168.88.2 ipv4.dns "8.8.8.8,8.8.4.4" ipv4.method manual
+```
+
+- 启动/停止接口
+
+```bash
+[root@localhost ~]# nmcli connection down ens160
+[root@localhost ~]# nmcli connection up ens160
+```
+
+- 创建链接
+
+```bash
+[root@localhost ~]# nmcli connection add type ethernet ifname ens160 con-name dhcp_ens160
+# 激活链接
+[root@localhost ~]# nmcli connection up dhcp_ens160
+```
+
+- 删除链接
+
+```bash
+[root@localhost ~]# nmcli connection delete dhcp_ens160
+成功删除连接 'dhcp_ens160'(37adadf4-419d-47f0-a0f6-af849160a4f7)。
+```
+
+
+
+# 5. ifconfig
+
+- ifconfig 命令用于显示或设置网络设备。
+
+**安装:**`yum install -y net-tools`
+
+## 5.1 语法
+
+```bash
+ifconfig [network_interface]
+ [down|up]
+ [add
+
+**软件防火墙:**
+
+软件防火墙就是通过软件来对数据包,流量请求进行过滤等,属于从软件层面保护系统的安全。如我们熟知的360,金山毒霸,火绒安全等等。
+
+当然防火墙除了软件及硬件的分类,也可以对数据封包的取得方式来分类,可分为**代理服务器(Proxy)**及**封包过滤机制(IP Filter)**。
+
+- 代理服务
+
+ - 是一种网络服务,通常就架设在路由上面,可完整的掌控局域网的对外连接。
+
+- IP Filter
+
+ - 这种方式可以直接分析最底层的封包表头数据来进行过滤,所以包括 MAC地址, IP, TCP, UDP, ICMP 等封包的信息都可以进行过滤分析的功能,用途非常广泛。
+
+ 相较于企业内网,外部的公网环境更加恶劣,罪恶丛生。在公网与企业内网之间充当保护屏障的防火墙虽然有软件或硬件之分,但主要功能都是依据策略对穿越防火墙自身的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后防火墙使用预先定制的策略规则监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。这样一来,就可以保证仅有合法的流量在企业内网和外部公网之间流动了
+
+# 2. RHEL/Centos系统
+
+对于RHEL、Centos等红帽系Linux操作系统,我们常用到的防火墙软件主要有**iptables和firewalld**
+
+- iptables:
+ - iptables 是 Linux 默认的防火墙管理工具,它是基于命令行的。
+ - iptables 使用规则表(tables)和规则链(chains)的方式来控制网络数据包的流向和处理。
+ - iptables 提供了强大的灵活性和细粒度的控制,可以根据数据包的各种属性进行复杂的过滤和转发操作。
+ - iptables 的配置相对比较复杂,需要对防火墙的工作原理有一定的了解。
+- firewalld:
+ - firewalld 是 RHEL/CentOS 7 及以后版本中引入的动态防火墙管理工具。
+ - firewalld 采用区域(zones)和服务(services)的概念来管理防火墙规则,相比 iptables 更加简单和易用。
+ - firewalld 支持动态更新防火墙规则,无需重启服务即可生效,这对于需要经常调整防火墙的场景很有帮助。
+ - firewalld 提供了图形化的管理界面,方便管理员进行配置和管理。
+
+
+
+**不过,对于Linux而言,其实Iptables和firewalld服务不是真正的防火墙,只是用来定义防火墙规则功能的"防火墙管理工具",将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能。**
+
+
+
+# 3. iptables
+
+iptables过滤数据包的方式:
+
+- 允许/拒绝让 Internet 的封包进入 Linux 主机的某些 port
+
+- 允许/拒绝让某些来源 IP 的封包进入
+
+- 允许/拒绝让带有某些特殊标志( flag )的封包进入
+
+- 分析硬件地址(MAC)来提供服务
+
+## 3.1 五链
+
+iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链,叫规则链。
+规则链则依据处理数据包的位置不同分类:
+
+- PREROUTING
+ - 在进行路由判断之前所要进行的规则(DNAT/REDIRECT)
+- INPUT
+ - 处理入站的数据包
+- OUTPUT
+ - 处理出站的数据包
+- FORWARD
+ - 处理转发的数据包
+- POSTROUTING
+ - 在进行路由判断之后所要进行的规则(SNAT/MASQUERADE)
+
+
+
+## 3.2 四表
+
+iptables中的规则表是用于容纳规则链,规则表默认是允许状态的,那么规则链就是设置被禁止的规则,而反之如果规则表是禁止状态的,那么规则链就是设置被允许的规则。
+
+- raw表
+ - 确定是否对该数据包进行状态跟踪
+- mangle表
+ - 为数据包设置标记(较少使用)
+- nat表
+ - 修改数据包中的源、目标IP地址或端口
+- filter表
+ - 确定是否放行该数据包(过滤)
+
+
+
+规则表的先后顺序:0000
+
+规则链的先后顺序:
+
+- 入站顺序
+ - PREROUTING→INPUT
+- 出站顺序
+ - OUTPUT→POSTROUTING
+- 转发顺序
+ - PREROUTING→FORWARD→POSTROUTING
+
+
+
+## 3.3 基本选项和用法
+
+### 3.3.1 选项
+
+| 参数 | 作用 |
+| ------------ | ----------------------------------------------------------- |
+| -P | 设置默认策略:iptables -P INPUT (DROP\|ACCEPT)类似于黑白名单 |
+| -F | 清空规则链 |
+| -L | 查看规则链 |
+| -A | 在规则链的末尾加入新规则 |
+| -I num | 在规则链的头部加入新规则 |
+| -D num | 删除某一条规则 |
+| -s | 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。 |
+| -d | 匹配目标地址 |
+| -i 网卡名称 | 匹配从这块网卡流入的数据 |
+| -o 网卡名称 | 匹配从这块网卡流出的数据 |
+| -p | 匹配协议,如tcp,udp,icmp |
+| --dports num | 匹配目标端口号 |
+| --sports num | 匹配来源端口号 |
+
+
+
+为了防止firewalld与iptables的冲突,建议在学习iptables的时候,先关闭firewalld
+
+
+
+### 3.3.2 简单用法(初体验)
+
+案例:现在有一个web服务提供网站访问,默认情况下是允许被我们的主机访问的,我们可以尝试通过设置iptables的策略,来禁止别人访问该网站
+
+- 为了防止firewalld对iptables的影响,我们学习iptables的时候应该关闭firewalld
+
+```bash
+[root@localhost ~]# systemctl stop firewalld
+```
+
+- 网站部署:
+
+```bash
+[root@localhost ~]# yum install -y epel-release
+# 安装扩展源,以便安装下面的web服务器nginx
+[root@localhost ~]# yum install -y nginx
+# 安装web服务器
+[root@localhost ~]# systemctl start nginx
+# 启动web服务器
+```
+
+- 访问测试:
+
+```shell
+curl -I x.x.x.x
+```
+
+- 接下来通过iptables进行访问控制
+
+```bash
+[root@localhost ~]# iptables -A INPUT -p tcp --dport 80 -j DROP
+# 对INPUT链上增加一个策略,丢弃掉来自80端口tcp协议的请求报文
+```
+
+- 再次访问发现,这个网站已经打不开了,提示回应超时!
+
+```shell
+curl -I x.x.x.x
+```
+
+- 在Linux上查看刚刚添加的过滤规则
+
+```bash
+[root@localhost ~]# iptables -vnL INPUT --line-numbers
+Chain INPUT (policy ACCEPT 62 packets, 4776 bytes)
+num pkts bytes target prot opt in out source destination
+1 75 3900 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
+```
+
+## 3.4 iptables规则说明
+
+- 规则:根据指定的匹配条件来尝试匹配每个经流“关卡”的报文,一旦匹配成功,则由规则后面指定的处理动作进行处理
+- 匹配条件
+ - 基本匹配条件:sip、dip
+ - 扩展匹配条件:sport、dport
+ - 扩展条件也是条件的一部分,只不过使用的时候需要用`-m`参数声明对应的模块
+- 处理动作
+ - accept:接受
+ - drop:丢弃
+ - reject:拒绝
+ - snat:源地址转换,解决内网用户同一个公网地址上上网的问题
+ - masquerade:是snat的一种特殊形式,使用动态的、临时会变的ip上
+ - dnat:目标地址转换
+ - redirect:在本机作端口映射
+ - log:记录日志,/var/log/messages文件记录日志信息,然后将数据包传递给下一条规则
+
+
+
+## 3.5 iptables高级用法
+
+
+
+- `-t table`指定表
+ - raw
+ - mangle
+ - nat
+ - filter 默认
+- `-A`:添加规则,后面更上你要添加到哪个链上
+- `-j`:设置处理策略
+ - accept:接受
+ - drop:丢弃
+ - reject:拒绝
+- `-s`:指定数据包的来源地址
+- `-p`:指定数据包协议类型
+ - tcp
+ - udp
+ - icmp
+ - ......
+
+### 3.5.1 增加规则
+
+**案例一:**屏蔽来自其他主机上的ping包
+
+```bash
+# 正常通过cmd去ping我们的虚拟机的IP地址
+C:\Users\Atopos>ping 192.168.88.136
+
+正在 Ping 192.168.88.136 具有 32 字节的数据:
+来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
+来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
+来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
+来自 192.168.88.136 的回复: 字节=32 时间<1ms TTL=64
+
+192.168.88.136 的 Ping 统计信息:
+ 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
+往返行程的估计时间(以毫秒为单位):
+ 最短 = 0ms,最长 = 0ms,平均 = 0ms
+
+
+# 在虚拟机上屏蔽来自我们物理机的ping包,注意物理机的IP的地址为:192.168.xxx.1
+# ping命令是基于icmp协议的,所以这里对类型为icmp协议的数据包进行丢弃
+[root@localhost ~]# iptables -A INPUT -s 192.168.88.1 -p icmp -j DROP
+
+# 丢弃以后ping测试:
+C:\Users\Atopos>ping 192.168.88.136
+
+正在 Ping 192.168.88.136 具有 32 字节的数据:
+请求超时。
+
+# 注意,DROP和REJECT有一定的区别,DROP为丢弃数据包,不给予对方回应,所以对方就会一直等待。REJECT是拒绝对方,会将拒绝的数据包发给对方,对方就会知道我们拒绝的访问。
+# 如果改成REJECT现象是:
+C:\Users\Atopos>ping 192.168.88.136
+
+正在 Ping 192.168.88.136 具有 32 字节的数据:
+来自 192.168.88.136 的回复: 无法连到端口。
+来自 192.168.88.136 的回复: 无法连到端口。
+来自 192.168.88.136 的回复: 无法连到端口。
+来自 192.168.88.136 的回复: 无法连到端口。
+
+192.168.88.136 的 Ping 统计信息:
+ 数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
+
+
+`其他用法`
+[root@localhost ~]# iptables -A INPUT -s 192.168.88.100 -j ACCEPT
+# 目标来自 192.168.88.100 这个 IP 的封包都予以接受
+[root@localhost ~]# iptables -A INPUT -s 192.168.88.0/24 -j ACCEPT
+[root@localhost ~]# iptables -A INPUT -s 192.168.88.10 -j DROP
+# 192.168.88.0/24 可接受,但 192.168.88.10 丢弃
+```
+
+**案例二:**屏蔽Linux系统中的远程链接服务(sshd),使得我们无法通过MobaXterm连接到虚拟机上
+
+```bash
+[root@localhost ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
+# ssh服务所用的协议类型为tcp协议,端口号为22
+# 所以我们将来自22端口上的tcp协议数据包给拒绝
+```
+
+当敲完这个命令以后,你的远程连接就会中断了,可以在VMware中的虚拟机终端上删除这个规则,就恢复了
+
+删除命令:`iptables -D INPUT -p tcp --dport 22 -j REJECT`
+
+
+
+### 3.5.2 查看规则
+
+```bash
+[root@localhost ~]# iptables [-t tables] [-L] [-nv]
+参数:
+-t 后面接table,例如nat或filter,如果省略,默认显示filter
+-L 列出目前的table的规则
+-n 不进行IP与主机名的反查,显示信息的速度会快很多
+-v 列出更多的信息,包括封包数,相关网络接口等
+--line-numbers 显示规则的序号
+```
+
+- 查看具体每个表的规则
+
+ - policy:当前链的默认策略,当所有规则都没有匹配成功时执行的策略
+ - packets:当前链默认策略匹配到的包的数量
+ - bytes:当前链默认策略匹配到的包的大小
+ - pkts:对应规则匹配到的包数量
+ - bytes:对应规则匹配到的包大小
+ - target:对应规则执行的动作
+ - prot:对应的协议,是否针对某些协议应用此规则
+ - opt:规则对应的选项
+ - in:数据包由哪个接口流入
+ - out:数据包由哪个接口流出
+ - source:源ip地址
+ - distination:目的ip地址
+
+```bash
+[root@localhost ~]# iptables -vnL INPUT -t filter --line-numbers
+[root@localhost ~]# iptables -nL -t nat
+[root@localhost ~]# iptables -nL -t mangle
+[root@localhost ~]# iptables -nL -t raw
+```
+
+
+
+### 3.5.3 删除规则
+
+通过上面学习的查看规则的方法,先查找到你想要删除的规则
+
+```bash
+# 举例
+# 查看nat表上所有链的规则
+[root@localhost ~]# iptables -t nat -nL --line-numbers
+# 查看filter(默认表)上所有链的规则
+[root@localhost ~]# iptables -nL --line-numbers
+```
+
+- 通过num序号进行删除
+
+```bash
+删除input链上num为1的规则
+[root@localhost ~]# iptables -D INPUT 1
+```
+
+- 通过规则匹配删除
+
+```bash
+[root@localhost ~]# iptables -D INPUT -p tcp --dport 80 -j DROP
+```
+
+- 清空所有的规则
+
+```bash
+[root@localhost ~]# iptables -F
+```
+
+
+
+### 3.5.4 修改规则
+
+方案一:通过`iptables -D`删除原有的规则后添加新的规则
+
+方案二:通过`iptables -R`可以对具体某一个num的规则进行修改
+
+```bash
+# 修改端口的为8080
+[root@localhost ~]# iptables -R INPUT 1 -p tcp --dport 8080 -j ACCEPT
+
+# 针对具体的某一个表和链进行修改
+# 将8080修改回80
+[root@localhost ~]# iptables -t filter -R INPUT 1 -p tcp --dport 80 -j ACCEPT
+```
+
+
+
+## 3.6 自定义链
+
+iptables中除了系统自带的五个链之外,还可以自定义链,来实现将规则进行分组,重复调用的目的
+
+具体方法见如下案例:
+
+案例一:我们自定义一个WEB_CHAIN链,专门管理跟web网站相关的规则策略
+
+```bash
+# 1. 先查看我们现有的系统链
+[root@localhost ~]# iptables -L
+Chain INPUT (policy ACCEPT)
+target prot opt source destination
+Chain FORWARD (policy ACCEPT)
+target prot opt source destination
+Chain OUTPUT (policy ACCEPT)
+target prot opt source destination
+
+# 2. 添加WEB_CHAIN自定义链,并且查看
+[root@localhost ~]# iptables -t filter -N web_chain
+[root@localhost ~]# iptables -L
+..........
+Chain web_chain (0 references)
+target prot opt source destination
+
+# 3. 可以通过-E参数修改自定义链
+[root@localhost ~]# iptables -t filter -E web_chain WEB_CHAIN
+[root@localhost ~]# iptables -L
+.........
+Chain WEB_CHAIN (0 references)
+target prot opt source destination
+# 可以看到名字已经发生变化了
+
+# 4. 向我们创建的自定义链中添加规则,开放80端口上的服务
+[root@localhost ~]# iptables -t filter -A WEB_CHAIN -p tcp -m multiport --dports 80,443 -j ACCEPT
+
+# 5. 将自定义链关联到系统链上才能使用
+# 因为数据包只会经过上面讲过的五个系统链,不会经过我们的自定义链,所以需要把自定义链关联到某个系统链上
+
+# 我们允许来自IP:192.168.88.1的访问,随后拒绝其他所有的访问,这样,只有192.168.88.1的主机可以访问这个网站
+[root@localhost ~]# iptables -t filter -A INPUT -s 192.168.88.1 -j WEB_CHAIN
+[root@localhost ~]# iptables -t filter -A INPUT -p tcp -m multiport --dports 80,443 -j DROP
+[root@localhost ~]# iptables -L
+Chain INPUT (policy ACCEPT)
+target prot opt source destination
+WEB_CHAIN all -- 192.168.88.1 anywhere
+Chain FORWARD (policy ACCEPT)
+target prot opt source destination
+Chain OUTPUT (policy ACCEPT)
+target prot opt source destination
+Chain WEB_CHAIN (1 references)
+target prot opt source destination
+ACCEPT tcp -- anywhere anywhere tcp dpt:http
+
+```
+
+访问测试:
+
+```shell
+# windows本身可以访问我们的网站,但是其他主机无法访问
+curl -I x.x.x.x
+```
+
+删除自定义链
+
+```shell
+# 先清空自定义链上的规则
+[root@localhost ~]# iptables -t filter -F WEB_CHAIN
+# 然后通过-X选项删除自定义链
+[root@localhost ~]# iptables -t filter -X WEB_CHAIN
+```
+
+## 3.7 其他用法(模块)
+
+- tcp/udp
+ - --dport:指定目的端口
+ - --sport:指定源端口
+
+- iprange:匹配报文的源/目的地址所在范围
+ - --src-range
+ - --dst-range
+
+```bash
+[root@localhost ~]# iptables -A INPUT -d 172.16.1.100 -p tcp --dport 80 -m iprange --src-range 172.16.1.5-172.16.1.10 -j DROP
+```
+
+- string:指定匹配报文中的字符串
+ - --algo:指定匹配算法,可以是bm/kmp
+ - bm:Boyer-Moore
+
+ - kmp:Knuth-Pratt-Morris
+ - --string:指定需要匹配的字符串
+ - --from offset:开始偏移
+ - --to offset:结束偏移
+
+```bash
+[root@localhost ~]# iptables -A OUTPUT -p tcp --sport 80 -m string --algo bm --from 62 --string "google" -j REJECT
+```
+
+**案例:**
+
+```shell
+[root@localhost ~]# yum -y install httpd
+[root@localhost ~]# systemctl start httpd
+[root@localhost ~]# systemctl enable httpd
+[root@localhost ~]# echo "
+
+**环境准备:**
+两台虚拟机,可以克隆一个出来,然后server1添加一张仅主机的网卡。为了模拟server2不能上网的情况,将server2上原有的网卡改成仅主机模式。
+
+由于server2的网卡修改成仅主机以后无法通过yum部署httpd,所以我们先在server2上部署一个Web网站
+
+```bash
+[root@localhost ~]# yum install -y httpd
+[root@localhost ~]# systemctl enable --now httpd
+# 确保关闭了firewalld,防止firewalld造成干扰
+[root@localhost ~]# systemctl disable --now firewalld
+
+# 检查80端口是否启动
+[root@localhost ~]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
+LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
+LISTEN 0 128 [::]:22 [::]:*
+LISTEN 0 511 *:80 *:*
+```
+
+**server1:**
+
+
+
+**server2:**
+
+
+
+
+第一步:配置仅主机模式网卡的IP地址,其中:
+
+**server1:**
+
+ IP:192.168.12.1/24
+
+**server2:**
+
+ IP:192.168.12.2/24
+
+ 网关:192.168.12.1 # 网关指向server1的地址
+
+ dns:114.114.114.114
+
+第二步:在server1的Linux内核中开启数据转发功能
+
+```bash
+- 开启数据转发
+[root@localhost ~]# echo "net.ipv4.ip_forward=1" >> /usr/lib/sysctl.d/50-default.conf
+[root@localhost ~]# sysctl -w net.ipv4.ip_forward=1
+[root@localhost ~]# sysctl -p
+
+或者:
+[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
+
+禁止数据转发:
+[root@localhost ~]# echo 0 > /proc/sys/net/ipv4/ip_forward
+```
+
+第三步:访问测试
+
+- server2访问外网测试
+
+ `ping www.baidu.com`
+
+- Windows访问server2上的网站测试
+
+### 3.9.2 配置SNAT让server2能够网上冲浪
+
+server1上操作:
+
+```bash
+[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j SNAT --to-source 192.168.88.136
+
+- POSTROUTING:数据包出口链
+- SNAT:将源地址进行转发
+
+也可以使用如下写法(PAT):
+[root@localhost ~]# iptables -t nat -A POSTROUTING -s 192.168.12.0/24 -j MASQUERADE
+```
+
+server2上测试网络连通性:
+
+`ping www.baidu.com`
+
+并且通过对Vmnet 8网卡抓包查看,虽然我们是用server去ping百度。但是却能抓到server1的ens160网卡发往百度的ping包
+
+
+
+### 3.9.3 配置DNAT使得可以访问server2中的内部网站
+
+```bash
+[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.12.2:80
+
+# 在PREROUTING链上将来自8080端口上的访问转发到内网中的192.168.88.12.2上的80端口
+
+`访问测试:`
+浏览器中输入:192.168.88.136:8080
+
+- 扩展案例:
+- 配置DNAT来映射server2上的ssh服务
+[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 3322 -j DNAT --to-destination 192.168.12.2:22
+
+`连接测试:`
+ssh root@192.168.88.136 -p 3322
+```
+
+
+
+## 3.10 案例二:转发本地端口
+
+```bash
+[root@localhost ~]# iptables -t nat -A PREROUTING -p tcp --dport 6666 -j REDIRECT --to-port 22
+# 此时连接6666端口,iptables会帮我们转发到22端口
+```
+
+
+
+# 4. Firewalld
+
+Firewalld是CentOS 7.0新推出的管理netfilter的用户空间软件工具
+
+并且支持划分区域zone,每个zone可以设置独立的防火墙规则
+
+- 流量的规则匹配顺序
+ - 先根据数据包中源地址,将其纳为某个zone
+ - 纳为网络接口所属zone
+ - 纳入默认zone,默认为public zone,管理员可以改为其它zone
+
+- firewalld中常用的区域名称及策略规则
+
+| 区域 | 默认策略规则 |
+| -------- | ------------------------------------------------------------ |
+| public | 默认区域,对应普通网络环境。允许选定的连接,拒绝其他连接 |
+| drop | 所有传入的网络包都会被直接丢弃,不会发送任何响应 |
+| block | 所有传入的网络包会被拒绝,并发送拒绝信息 |
+| external | 用于路由/NAT流量的外部网络环境。与public类似,更适用于网关、路由器等处理外部网络流量的设备 |
+| dmz | 隔离区域,只允许选定的连接,适用于部署公开服务的网络区域,如 Web 服务器,可以最大限度地降低内部网络的风险 |
+| work | 适用于工作环境,开放更多服务,如远程桌面、文件共享等。比 public 区域更加信任 |
+| home | 适用于家庭环境,开放更多服务,比如默认情况下会开放一些如:3074端口(Xbox)、媒体、游戏数据等待 |
+| trusted | 信任区域,允许所有连接 |
+
+## 4.1 firewall-cmd 管理工具
+
+| 参数 | 作用 |
+| ----------------------------- | ---------------------------------------------------- |
+| --get-default-zone | 查询默认的区域名称 |
+| --set-default-zone=<区域名称> | 设置默认的区域,使其永久生效 |
+| --get-zones | 显示可用的区域 |
+| --get-services | 显示预先定义的服务 |
+| --get-active-zones | 显示当前正在使用的区域与网卡名称 |
+| --add-source= | 将源自此IP或子网的流量导向指定的区域 |
+| --remove-source= | 不再将源自此IP或子网的流量导向某个指定区域 |
+| --add-interface=<网卡名称> | 将源自该网卡的所有流量都导向某个指定区域 |
+| --change-interface=<网卡名称> | 将某个网卡与区域进行关联 |
+| --list-all | 显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
+| --list-all-zones | 显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
+| --add-service=<服务名> | 设置默认区域允许该服务的流量 |
+| --add-port=<端口号/协议> | 设置默认区域允许该端口的流量 |
+| --remove-service=<服务名> | 设置默认区域不再允许该服务的流量 |
+| --remove-port=<端口号/协议> | 设置默认区域不再允许该端口的流量 |
+| --reload | 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则 |
+| --panic-on | 开启应急状况模式 |
+| --panic-off | 关闭应急状况模式 |
+| --permanent | 设定的当前规则保存到本地,下次重启生效 |
+
+
+
+## 4.2 简单用法(初体验)
+
+为了防止之前配置过的iptables规则导致与firewalld策略冲突,建议恢复快照后再开始练习
+
+通过web服务部署一个网站,然后访问测试
+
+```bash
+[root@localhost ~]# yum -y install httpd
+[root@localhost ~]# systemctl start httpd
+```
+
+在浏览器中输入`192.168.88.136`访问测试发现,我们无法访问此网站,这是因为默认情况下,firewalld是出于开启的状态,并且默认区域为public。在public区域中,除了部分系统服务,其他服务的流量一律是禁止的。
+
+```bash
+# 查看firewalld是否启用,可以看到当前是出于actice的状态
+[root@localhost ~]# systemctl status firewalld
+● firewalld.service - firewalld - dynamic firewall daemon
+ Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
+ Active: active (running) since 四 2024-05-23 15:39:56 CST; 28min ago
+ Docs: man:firewalld(1)
+ Main PID: 6264 (firewalld)
+ CGroup: /system.slice/firewalld.service
+ └─6264 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
+
+# 查看当前所在的区域
+[root@localhost ~]# firewall-cmd --get-default-zone
+public
+# 查看当前网卡所在的区域
+[root@localhost ~]# firewall-cmd --get-zone-of-interface=ens160
+public
+
+# 查询public区域是否允许请求SSH或者HTTP协议的流量
+[root@localhost ~]# firewall-cmd --zone=public --query-service=ssh
+yes
+[root@localhost ~]# firewall-cmd --zone=public --query-service=http
+no
+
+`可以看出,在public区域中,默认是禁止来自http协议的请求数据包的`
+
+```
+
+修改firewalld策略,使得我们可以访问到刚刚部署的网站
+
+```bash
+- 方法一:针对服务协议类型进行放行
+# 临时放行
+[root@localhost ~]# firewall-cmd --zone=public --add-service=http
+# 可以加上--permanent实现永久放行
+[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=http
+
+- 方法二:针对服务具体访问请求的端口号进行放行
+[root@localhost ~]# firewall-cmd --zone=public --add-port=80/tcp
+success
+# 同样也可以加上--permanent实现永久放行
+```
+
+以上方法二选一,然后访问测试
+
+```shell
+curl -I x.x.x.x
+```
+
+取消放行
+
+```bash
+[root@localhost ~]# firewall-cmd --zone=public --remove-service=http --permanent
+success
+```
+
+
+
+## 4.3 其他用法
+
+- 把firewalld服务的当前默认区域设置为public
+
+```bash
+[root@localhost ~]# firewall-cmd --set-default-zone=public
+Warning: ZONE_ALREADY_SET: public
+success
+[root@localhost ~]# firewall-cmd --get-default-zone
+public
+```
+
+- 查看某个区域的详细配置
+
+```bash
+[root@localhost ~]# firewall-cmd --zone=public --list-all
+public (active)
+ target: default
+ icmp-block-inversion: no
+ interfaces: ens33
+ sources:
+ services: ssh dhcpv6-client
+ ports: 80/tcp
+ protocols:
+ masquerade: no
+ forward-ports:
+ source-ports:
+ icmp-blocks:
+ rich rules:
+```
+
+- 将firewalld 切换到紧急模式(panic mode)。这种模式下,firewalld 会采取一种非常严格的防护策略:
+ 1. 所有传入的网络连接都会被拒绝,除了 ssh 和 ICMP 回送(ping)请求。
+ 2. 所有区域的防火墙规则都会被重置为默认的严格策略。
+ 3. 所有区域的默认策略都会被设置为 DROP
+
+```bash
+[root@localhost ~]# firewall-cmd --panic-on
+# 取消紧急模式
+[root@localhost ~]# firewall-cmd --panic-off
+```
+
+- 临时生效/永久生效
+
+```bash
+# 临时生效
+[root@localhost ~]# firewall-cmd --zone=public --add-service=http
+success
+# 永久生效,加了--permanent所进行的更改,会被写入到配置文件中,下次开机任然生效
+[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=http
+success
+# 使得最近对防火墙规则变更或者所作的修改生效
+[root@localhost ~]# firewall-cmd --reload
+success
+[root@localhost ~]# firewall-cmd --zone=public --query-service=http
+yes
+
+-配置文件路径
+/etc/firewalld/zones/public.xml
+/etc/firewalld/direct.xml
+/etc/firewalld/firewalld.conf
+```
+
+- 把firewalld服务中请求HTTPS协议的流量设置为永久拒绝,并立即生效
+
+```bash
+[root@localhost ~]# firewall-cmd --zone=public --remove-service=https --permanent
+success
+[root@localhost ~]# firewall-cmd --reload
+success
+```
+
+- 把在firewalld服务中访问8080和8081端口的流量策略设置为允许,当前生效
+
+```bash
+# 可以指定要开放端口的范围
+[root@localhost ~]# firewall-cmd --zone=public --add-port=8080-8081/tcp
+success
+[root@localhost ~]# firewall-cmd --zone=public --list-ports
+8080-8081/tcp
+```
+
+## 4.4 端口转发
+
+通过firewalld,将用户访问服务器上6666端口的流量转发到22端口上,实现本地端口映射。我们就可以使用6666端口来远程连接到服务器
+
+```bash
+[root@localhost ~]# firewall-cmd --permanent --add-forward-port=port=6666:proto=tcp:toport=22
+success
+[root@localhost ~]# firewall-cmd --reload
+```
+
+连接测试:
+
+```bash
+C:\Users\Atopos>ssh root@192.168.88.136 -p 6666
+root@192.168.88.136's password:
+Last login: Thu May 23 21:20:38 2024 from 192.168.88.1
+[root@localhost ~]#
+可以看到我们通过6666端口成功连接到我们的虚拟机
+```
+
+## 4.5 firewalld富规则
+
+富规则是 firewalld 提供的一种灵活且强大的防火墙规则配置方式。与简单的端口和服务规则不同,富规则支持更复杂的匹配条件和操作。
+
+使用富规则,可以实现复杂的防火墙策略,例如:
+
+- 允许特定 IP 地址访问某个端口
+- 拒绝特定 IP 地址访问某个服务
+- 限制某个网段的连接频率
+- 转发某个端口到另一个端口
+
+**富规则的配置方法:**
+
+`firewall-cmd --permanent --add-rich-rule='
+
+选择生成的密钥对类型以及点击Generator生成
+
+
+
+生成密钥对并且保存公钥和私钥
+
+生成的时候,要鼠标不断移动,该工具会根据鼠标移动的坐标,来生成随机的密钥
+
+
+
+
+
+服务端 `.ssh` 目录下新建文件`authorized_keys`,将上面生成的密钥粘进去
+
+
+
+如果连接失败,原因是由于我们通过 mobaxterm 生成的密钥文件权限不满足要求,并且在 windows 上修改权限的话非常麻烦。所以我们可以考虑通过在 cmd 命令行中使用 ssh-keygen 工具来生成密钥文件。
+
+
+
+可以看到生成的公钥和私钥
+
+
+
+打开公钥文件,复制其中的内容,在 Linux 中的 /root.ssh/authorized_keys 文件中粘贴
+
+然后继续通过 cmd 连接测试:
+
+
+
+也可以尝试使用 Mobaxterm 工具,选择私钥进行连接。但是 Mobaxterm 连接的时候也可能会遇到报错的问题。这个是受不同工具的影响。如果通过 cmd 能够连接成功的话。就说明我们的密钥和配置是正常的。
\ No newline at end of file
diff --git a/02.企业服务/01.SSH远程管理/SSH密钥生成器01.png b/02.企业服务/01.SSH远程管理/SSH密钥生成器01.png
new file mode 100644
index 0000000..ca8c919
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/SSH密钥生成器01.png differ
diff --git a/02.企业服务/01.SSH远程管理/SSH密钥生成器02.png b/02.企业服务/01.SSH远程管理/SSH密钥生成器02.png
new file mode 100644
index 0000000..b27e61d
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/SSH密钥生成器02.png differ
diff --git a/02.企业服务/01.SSH远程管理/SSH密钥生成器03.png b/02.企业服务/01.SSH远程管理/SSH密钥生成器03.png
new file mode 100644
index 0000000..5547228
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/SSH密钥生成器03.png differ
diff --git a/02.企业服务/01.SSH远程管理/authorized_keys文件.png b/02.企业服务/01.SSH远程管理/authorized_keys文件.png
new file mode 100644
index 0000000..4f9964d
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/authorized_keys文件.png differ
diff --git a/02.企业服务/01.SSH远程管理/ssh-keygen命令.png b/02.企业服务/01.SSH远程管理/ssh-keygen命令.png
new file mode 100644
index 0000000..4d5eaba
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/ssh-keygen命令.png differ
diff --git a/02.企业服务/01.SSH远程管理/公私钥文件.png b/02.企业服务/01.SSH远程管理/公私钥文件.png
new file mode 100644
index 0000000..92e08c1
Binary files /dev/null and b/02.企业服务/01.SSH远程管理/公私钥文件.png differ
diff --git a/02.企业服务/02.Samba文件共享.md b/02.企业服务/02.Samba文件共享.md
new file mode 100644
index 0000000..efbd9e3
--- /dev/null
+++ b/02.企业服务/02.Samba文件共享.md
@@ -0,0 +1,468 @@
+# 1. Samba文件共享
+
+## 1.1 什么是Samba
+
+Samba 是一个开源软件套件,允许 Linux/Unix 系统与 Windows 系统之间实现文件共享和打印服务。Samba 使用 SMB(Server Message Block)/CIFS(Common Internet File System)协议,这些协议是 Windows 系统共享资源的基础。
+
+## 1.2 发展历程
+
+**1992 年**:Samba 项目由 Andrew Tridgell 发起,最初作为一个简单工具来查看 DOS 文件共享。
+
+**1994 年**:Samba 正式命名,支持 SMB 协议。
+
+**1996 年**:开始支持 Windows NT 域。
+
+**2003 年**:引入 LDAP 集成,支持 Active Directory。
+
+**2012 年**:Samba 4 发布,完全实现了 Active Directory 的功能。
+
+**现在**:Samba 成为企业级跨平台文件共享的核心工具之一。
+
+## 1.3 Samba用途
+
+**文件共享**:允许用户在不同操作系统之间共享文件。
+
+**打印服务**:提供跨平台的打印服务和在线编辑。
+
+**域控制器**:Samba 可以用作 Windows 网络的域控制器。
+
+**认证与授权**:支持用户认证、访问控制和权限管理。
+
+**跨平台互操作性**:让 Linux/Unix 系统与 Windows 系统无缝协作。
+
+Windows计算机网络管理模式:
+
+* 工作组WORKGROUP:计算机对等关系,帐号信息各自管理
+* 域DOMAIN:C/S结构,帐号信息集中管理,DC,AD
+
+## 1.4 Samba相关软件包介绍
+
+在 Rocky Linux 中,Samba 的核心组件包含以下软件包:
+
+- **samba**:Samba 的主包,包括核心服务和工具。
+- **samba-client**:提供客户端工具,用于访问远程的 SMB/CIFS 共享。
+- **samba-common**:共享的配置文件和库。
+- **samba-libs**:Samba 运行所需的库。
+- **samba-common-tools**:包含测试和管理工具,例如 `smbstatus`。
+- **smbclient**:命令行工具,用于访问 SMB/CIFS 共享。
+- **cifs-utils**:提供挂载 SMB 文件系统的工具(如 `mount.cifs`)。
+
+## 1.5 相关服务进程
+
+**smbd**:提供文件共享和打印服务,TCP:139、445。
+
+**nmbd**:负责 NetBIOS 名称解析和浏览功能,UDP:137、138。
+
+**winbindd**:用于与 Windows 域集成,支持用户和组的认证。
+
+**samba-ad-dc**:Samba 4 中的域控制器服务。
+
+## 1.6 Samba主配置文件
+
+主配置文件:/etc/samba/smb.conf 帮助参看:man smb.conf
+
+语法检查: testparm [-v] [/etc/samba/smb.conf]
+
+```bash
+[global]
+ workgroup = WORKGROUP # 工作组名称
+ server string = Samba Server # 服务器描述
+ security = user # 认证模式
+ log file = /var/log/samba/log.%m # 日志文件路径
+ max log size = 50 # 最大日志文件大小(KB)
+ dns proxy = no # 禁用 DNS 代理
+
+[shared]
+ path = /srv/samba/shared # 共享路径
+ browseable = yes # 是否可浏览
+ writable = yes # 是否可写
+ valid users = @smbgroup # 允许访问的用户/组
+```
+
+### 1.6.1 全局设置([global])
+
+- `workgroup`:指定工作组名称,默认是 `WORKGROUP`。
+- security:
+ - `user`:用户级认证(常用)。
+ - `share`:共享级认证(不推荐)。
+ - `domain`:域级认证。
+ - `ads`:Active Directory 服务。
+- `log file`:日志文件路径。
+- `max log size`:限制日志文件大小。
+
+### 1.6.2 共享设置([共享名])
+
+- `path`:共享目录的路径。
+- `browseable`:决定共享是否可被浏览。
+- `writable`:是否允许写入。
+- `valid users`:指定允许访问的用户或组。
+
+# 2. 快速开始
+
+## 2.1 安装Samba服务
+
+```bash
+[root@localhost ~]# yum -y install samba
+[root@localhost ~]# systemctl enable --now smb
+[root@localhost ~]# systemctl enable --now nmb
+[root@localhost ~]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
+LISTEN 0 50 0.0.0.0:445 0.0.0.0:*
+LISTEN 0 50 0.0.0.0:139 0.0.0.0:*
+LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
+LISTEN 0 50 [::]:445 [::]:*
+LISTEN 0 50 [::]:139 [::]:*
+LISTEN 0 128 [::]:22 [::]:*
+```
+
+在`ss`命令的输出中,`Recv-Q`和`Send-Q`是与TCP连接相关的两个队列的大小。
+
+- `Recv-Q`表示接收队列的大小。它指示了尚未被应用程序(进程)接收的来自网络的数据的数量。当接收队列的大小超过一定限制时,可能会发生数据丢失。
+- `Send-Q`表示发送队列的大小。它指示了应用程序(进程)等待发送到网络的数据的数量。当发送队列的大小超过一定限制时,可能会导致发送缓冲区已满,从而阻塞应用程序发送更多的数据。
+
+## 2.2 配置Samba用户
+
+* 包:samba-common-tools
+* 工具:smbpasswd pdbedit
+* 用户数据库:/var/lib/samba/private/passdb.tdb
+
+说明:samba用户须是Linux用户,建议使用/sbin/nologin
+
+一、创建系统用户
+
+```bash
+[root@localhost ~]# useradd -s /sbin/nologin smbuser
+[root@localhost ~]# echo 123 | passwd --stdin smbuser
+Changing password for user smbuser.
+passwd: all authentication tokens updated successfully.
+```
+
+二、创建Samba用户
+
+```bash
+[root@localhost ~]# smbpasswd -a smbuser
+New SMB password:
+Retype new SMB password:
+Added user smbuser.
+[root@localhost ~]# smbpasswd -e smbuser # 启用用户
+Enabled user smbuser.
+```
+
+三、其他操作(视具体情况而使用)
+
+* 如果已经存在,想修改密码
+
+```shell
+[root@localhost ~]# smbpasswd smb1
+```
+
+* 想要删除用户和密码
+
+```shell
+[root@localhost ~]# smbpasswd -x smb1
+[root@localhost ~]# pdbedit -x -u smb1
+```
+
+* 查看samba用户列表
+
+```shell
+[root@localhost ~]# pdbedit -L -v
+```
+
+* 查看samba服务器状态
+
+```shell
+[root@localhost ~]# yum install -y samba
+[root@localhost ~]# smbstatus
+```
+
+## 2.3 基于特定用户或组的共享
+
+### 2.3.1 服务端操作
+
+一、创建共享目录
+
+共享目录为:`/data/samba`
+
+```bash
+[root@localhost ~]# mkdir -p /data/samba
+[root@localhost ~]# chown -R smbuser:smbuser /data/samba
+[root@localhost ~]# chmod -R 2770 /data/samba
+```
+
+二、添加配置文件
+
+```bash
+[root@localhost ~]# vim /etc/samba/smb.conf
+......
+[shared]
+ path = /data/samba
+ browseable = yes
+ writable = yes
+ valid users = @smbuser
+ create mask = 0660
+ directory mask = 2770
+```
+
+三、关闭防火墙与SELinux
+
+```bash
+[root@localhost ~]# systemctl stop firewalld
+[root@localhost ~]# setenforce 0
+```
+
+四、重启smb服务
+
+```bash
+[root@localhost ~]# systemctl restart smb
+[root@localhost ~]# systemctl restart nmb
+```
+
+### 2.3.2 客户端操作
+
+#### 2.3.2.1 Windows连接
+
+一、在运行窗口中输入:`\\192.168.88.10\`进行连接
+
+
+
+二、用户验证:smbuser/123
+
+三、文件创建写入测试
+
+
+
+四、Samba服务端中查看
+
+```bash
+[root@localhost ~]# cat /data/samba/file.txt
+The file is Created by windows...
+```
+
+#### 2.3.2.2 Linux连接
+
+一、客户端工具下载
+
+```bash
+[root@localhost ~]# yum -y install samba-client
+```
+
+二、创建上传测试文件
+
+```bash
+[root@localhost ~]# echo "In server2..." > server2.txt
+```
+
+三、使用smbclient连接服务器测试
+
+```bash
+[root@localhost ~]# smbclient -L 192.168.88.10 -U smbuser
+Password for [SAMBA\smbuser]:
+
+ Sharename Type Comment
+ --------- ---- -------
+ print$ Disk Printer Drivers
+ shared Disk
+ IPC$ IPC IPC Service (Samba 4.20.2)
+ smbuser Disk Home Directories
+SMB1 disabled -- no workgroup available
+[root@localhost ~]# smbclient //192.168.88.10/shared -U smbuser
+Password for [SAMBA\smbuser]:
+Try "help" to get a list of possible commands.
+smb: \> ls
+ . D 0 Sat Jan 11 11:06:08 2025
+ .. D 0 Sat Jan 11 11:06:08 2025
+ file.txt A 33 Sat Jan 11 10:51:54 2025
+
+ 17756160 blocks of size 1024. 16032064 blocks available
+smb: \> get file.txt # 下载文件
+getting file \file.txt of size 33 as file.txt (16.1 KiloBytes/sec) (average 16.1 KiloBytes/sec)
+smb: \> put /server2.txt # 上传文件
+putting file /server2.txt as \server2.txt (4.6 kb/s) (average 4.6 kb/s)
+```
+
+### 2.3.3 挂载CIFS文件系统
+
+手动挂载:
+
+```bash
+[root@localhost ~]# yum install -y cifs-utils
+[root@localhost ~]# mkdir /mnt/smb
+[root@localhost ~]# mount -t cifs //192.168.88.10/shared /mnt/smb -o username=smbuser,password=123
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+tmpfs 175M 0 175M 0% /run/user/0
+//192.168.88.10/shared 17G 1.7G 16G 10% /mnt/smb
+[root@localhost ~]# cd /mnt/smb/
+[root@localhost smb]# ls
+file.txt server2.txt
+```
+
+开机自动挂载:
+
+```bash
+[root@localhost ~]# vim /etc/fstab
+//192.168.88.10/shared /mnt/smb cifs defaults,username=smbuser,password=123 0 0
+[root@localhost ~]# systemctl daemon-reload
+[root@localhost ~]# mount -a
+[root@localhost ~]# df -h
+Filesystem Size Used Avail Use% Mounted on
+devtmpfs 4.0M 0 4.0M 0% /dev
+tmpfs 872M 0 872M 0% /dev/shm
+tmpfs 349M 5.2M 344M 2% /run
+/dev/mapper/rl-root 17G 1.7G 16G 10% /
+/dev/nvme0n1p1 960M 261M 700M 28% /boot
+//192.168.88.10/shared 17G 1.7G 16G 10% /mnt/smb
+tmpfs 175M 0 175M 0% /run/user/0
+```
+
+# 3. 实战:不同账户访问不同目录
+
+## 3.1 服务端
+
+一、创建并启用用户
+
+创建三个samba用户,分别为smb1、smb2、smb3。密码均为:123
+
+```bash
+[root@localhost ~]# useradd -s /sbin/nologin -r smb1 # -r 不创建家目录
+[root@localhost ~]# useradd -s /sbin/nologin -r smb2
+[root@localhost ~]# useradd -s /sbin/nologin -r smb3
+[root@localhost ~]#
+[root@localhost ~]# smbpasswd -a smb1
+New SMB password:
+Retype new SMB password:
+Added user smb1.
+[root@localhost ~]# smbpasswd -a smb2
+New SMB password:
+Retype new SMB password:
+Added user smb2.
+[root@localhost ~]# smbpasswd -a smb3
+New SMB password:
+Retype new SMB password:
+Added user smb3.
+[root@localhost ~]# smbpasswd -e smb1
+Enabled user smb1.
+[root@localhost ~]# smbpasswd -e smb2
+Enabled user smb2.
+[root@localhost ~]# smbpasswd -e smb3
+Enabled user smb3.
+
+# 查看smb用户
+[root@localhost ~]# pdbedit -L
+smbuser:1000:
+smb2:986:
+smb1:987:
+smb3:985:
+```
+
+二、修改Samba配置文件如下
+
+```bash
+[root@localhost ~]# vim /etc/samba/smb.conf
+# 在global中添加该字段
+[global]
+config file = /etc/samba/conf.d/%U # 变量%U表示匹配用户名
+
+# 新建共享配置
+[share]
+ path = /data/samba/share
+ browseable = yes
+ writable = yes
+ Guest ok = yes
+ create mask = 0660
+ directory mask = 2770
+```
+
+三、配置共享目录和文件
+
+```bash
+[root@localhost ~]# mkdir -p /data/samba/share
+[root@localhost ~]# mkdir -p /data/samba/smb1
+[root@localhost ~]# mkdir -p /data/samba/smb2
+[root@localhost ~]# touch /data/samba/share/share.txt # 共享目录及文件
+[root@localhost ~]# touch /data/samba/smb1/smb1.txt # smb1目录及文件
+[root@localhost ~]# touch /data/samba/smb2/smb2.txt # smb2目录及文件
+[root@localhost ~]# tree /data/samba/
+/data/samba/
+├── file.txt
+├── server2.txt
+├── share
+│ └── share.txt
+├── smb1
+│ └── smb1.txt
+└── smb2
+ └── smb2.txt
+
+# 将/data/samba目录权限放开
+[root@localhost ~]# chmod 777 -R /data/samba
+```
+
+四、针对smb1用户和smb2用户单独编辑配置文件
+
+```bash
+[root@localhost ~]# vim /etc/samba/conf.d/smb1
+[share]
+ path = /data/samba/smb1
+ writable = yes
+ create mask = 0660
+ browseable = yes
+[root@localhost ~]# vim /etc/samba/conf.d/smb2
+[share]
+ path = /data/samba/smb2
+ writable = yes
+ create mask = 0660
+ browseable = yes
+```
+
+五、重启相关服务
+
+```bash
+[root@localhost ~]# systemctl restart smb
+[root@localhost ~]# systemctl restart nmb
+```
+
+## 3.2 客户端
+
+客户端访问测试
+
+```bash
+[root@localhost ~]# smbclient //192.168.88.10/share -U smb1
+Password for [SAMBA\smb1]:
+Try "help" to get a list of possible commands.
+smb: \> ls
+ . D 0 Sat Jan 11 15:00:58 2025
+ .. D 0 Sat Jan 11 15:00:58 2025
+ smb1.txt N 0 Sat Jan 11 15:00:58 2025
+
+ 17756160 blocks of size 1024. 16030864 blocks available
+smb: \> exit
+[root@localhost ~]# smbclient //192.168.88.10/share -U smb2
+Password for [SAMBA\smb2]:
+Try "help" to get a list of possible commands.
+smb: \> ls
+ . D 0 Sat Jan 11 15:00:03 2025
+ .. D 0 Sat Jan 11 15:00:03 2025
+ smb2.txt N 0 Sat Jan 11 15:00:03 2025
+
+ 17756160 blocks of size 1024. 16030864 blocks available
+smb: \> exit
+[root@localhost ~]# smbclient //192.168.88.10/share -U smb3
+Password for [SAMBA\smb3]:
+Try "help" to get a list of possible commands.
+smb: \> ls
+ . D 0 Sat Jan 11 14:59:44 2025
+ .. D 0 Sat Jan 11 14:59:44 2025
+ share.txt N 0 Sat Jan 11 14:59:44 2025
+
+ 17756160 blocks of size 1024. 16030884 blocks available
+```
+
+## 3.3 **结论**
+
+由此可以看出,我们通过针对不同用户编写子配置文件的方式来覆盖主配置文件中相同的共享。可以实现对于没有子配置的用户,访问主配置文件中的定义的目录。对于具备子配置的用户,访问子配置所定义的目录。实现控制不用用户登录访问不同目录。
\ No newline at end of file
diff --git a/02.企业服务/02.Samba文件共享/image-20250111104202425.png b/02.企业服务/02.Samba文件共享/image-20250111104202425.png
new file mode 100644
index 0000000..2b0ce25
Binary files /dev/null and b/02.企业服务/02.Samba文件共享/image-20250111104202425.png differ
diff --git a/02.企业服务/02.Samba文件共享/image-20250111105213658.png b/02.企业服务/02.Samba文件共享/image-20250111105213658.png
new file mode 100644
index 0000000..c33755e
Binary files /dev/null and b/02.企业服务/02.Samba文件共享/image-20250111105213658.png differ
diff --git a/02.企业服务/03.HTTP协议.md b/02.企业服务/03.HTTP协议.md
new file mode 100644
index 0000000..b64202a
--- /dev/null
+++ b/02.企业服务/03.HTTP协议.md
@@ -0,0 +1,180 @@
+# 1. HTTP 协议介绍
+
+HTTP(HyperText Transfer Protocol,超文本传输协议)是用于在客户端(通常是浏览器)和服务器之间传输超文本(如HTML)的应用层协议。它是无状态的、面向请求-响应的协议,基于TCP/IP传输。
+
+HTTP有不同版本号,不同版本号区别如下
+
+- HTTP0.9:仅支持 GET 方法,仅能访问 HTML 格式的资源
+- HTTP1.0:增加 POST 和 HEAD 方法,MIME 支持多种数据格式,开始支持 Cache,支持 tcp 短连接
+- HTTP1.1:支持持久连接(长连接),一个 TCP 连接允许多个请求,新增 PUT、PATCH、DELETE 等
+- HTTP2.0:性能大幅提升,新的二进制格式,多路复用,header 压缩,服务端推送
+
+# 2. HTTP 工作原理
+
+HTTP的工作过程可以总结为以下几个步骤:
+
+1. **建立连接:** 客户端(如浏览器)与服务器之间通过TCP三次握手建立连接。
+2. **发送请求:** 客户端向服务器(Apache、Nginx、IIS服务器)发送HTTP请求报文,请求资源或操作。
+3. **服务器处理请求:** HTTP服务器接收到请求后,处理请求并生成响应。
+4. **返回响应:** 服务器将响应报文返回给客户端。
+5. **断开连接:** 通常在响应完成后关闭TCP连接(HTTP/1.0默认短连接,HTTP/1.1支持长连接)。
+
+# 3. URL 与 URI
+
+## 3.1 URI(Uniform Resource Identifier)
+
+URI 是统一资源标识符,用于标识互联网上的资源。URI 分为两种
+
+- **URL(Uniform Resource Locator):** 统一资源定位符,用于描述资源的地址。
+
+- **URN(Uniform Resource Name):** 统一资源名称,用于标识资源的名称,不依赖物理位置
+
+## 3.2 URL(Uniform Resource Locator
+
+HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL 是一种特殊类型的URI,包含了用于查找某个资源的足够的信息
+
+URL 全称是 UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。以下面这个URL为例,介绍下普通URL的各部分组成:
+
+```shell
+http://iproute.cn:80/news/search?keyword=123&enc=utf8#name=321
+```
+
+从上面的URL可以看出,一个完整的URL包括以下几部分:
+
+1. **协议部分:** 该URL的协议部分为 `http:`,这代表网页使用的是HTTP 协议。在 Internet 中可以使用多种协议,如 HTTP,FTP 等等本例中使用的是 HTTP 协议。在 `http:` 后面的 `//` 为分隔符
+2. **域名(主机)部分:** 该 URL 的域名部分为 `iproute.cn`。一个URL 中,也可以使用 IP 地址作为域名使用
+3. **端口部分:** 跟在域名后面的是端口,域名和端口之间使用 `:` 作为分隔符。端口不是一个 URL 必须的部分,如果省略端口部分,将采用默认端口
+4. **虚拟目录部分:** 从域名后的第一个 `/` 开始到最后一个 `/` 为止,是虚拟目录部分。虚拟目录也不是一个 URL 必须的部分。本例中的虚拟目录是 `/news/`
+5. **文件名部分:** 从域名后的最后一个 `/` 开始到 `?` 为止,是文件名部分,如果没有 `?` ,则是从域名后的最后一个 `/` 开始到 `#` 为止,是文件部分,如果没有 `?` 和 `#`,那么从域名后的最后一个 `/` 开始到结束,都是文件名部分。本例中的文件名是 `search` 。文件名部分也不是一个 URL 必须的部分,如果省略该部分,则使用默认的文件名
+6. **参数部分:** 从 `?` 开始到 `#` 为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为 `keyword=123&enc=utf8`。参数可以允许有多个参数,参数与参数之间用 `&` 作为分隔符
+7. **锚部分:** 从 `#` 开始到最后,都是锚部分。本例中的锚部分是`name`。锚部分也不是一个 URL 必须的部分
+
+# 4. HTTP 注意事项
+
+1. HTTP 是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
+2. HTTP 是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过 HTTP 发送。客户端以及服务器指定使用适合的 MIME-type 内容类型。
+3. HTTP 是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
+
+# 5. HTTP 消息结构
+
+- HTTP 是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
+- HTTP 客户端是一个应用程序(Web 浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个 HTTP 的请求的目的。
+- HTTP 服务端是一个应用程序(通常是一个 Web 服务,如 Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送 HTTP 响应数据。
+- HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
+- HTTP 响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
+
+
+
+## 5.1 HTTP 请求报文
+
+客户端发送一个 HTTP 请求到服务器的请求消息包括以下格式:
+
+
+
+
+
+## 5.2 POST 和 GET 请求方法区别
+
+- 提交的过程
+ - GET 提交,请求的数据会附在URL之后(就是把数据放置在 HTTP 协议头中),以?分割URL和传输数据,多个参数用&连接
+ - POST 提交:把提交的数据放置在是HTTP包的包体中
+- 传输数据的大小
+ - 首先声明:HTTP协议没有对传输的数据大小进行限制,HTTP 协议规范也没有对URL长度进行限制
+ - GET 提交,特定浏览器和服务器对URL长度有限制
+ - POST 提交,由于不是通过URL传值,理论上数据不受限
+- 安全性
+ - POST 的安全性要比 GET 的安全性高
+ - 登录页面有可能被浏览器缓存,而缓存的是 URL
+ - 其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码
+ - 使用 GET 提交数据还可能会造成 Cross-site request forgery 攻击
+
+
+## 5.3 常见请求报文头部属性
+
+- Accpet
+ - 告诉服务端,客户端接收什么类型的响应
+- Referer
+ - 表示这是请求是从哪个URL进来的,比如想在网上购物,但是不知道选择哪家电商平台,你就去问百度,说哪家电商的东西便宜啊,然后一堆东西弹出在你面前,第一给就是某宝,当你从这里进入某宝的时候,这个请求报文的Referer 就是 `http://www.baidu.com`
+- Cache-Control
+ - 对缓存进行控制,如一个请求希望响应的内容在客户端缓存一年,或不被缓可以通过这个报文头设置
+- Accept-Encoding
+ - 这个属性是用来告诉服务器能接受什么编码格式,包括字符编码,压缩格式
+- Host
+ - 指定要请求的资源所在的主机和端口
+- User-Agent
+ - 告诉服务器,客户端使用的操作系统、浏览器版本和名称
+
+
+## 5.4 HTTP 响应报文
+
+服务的相应信息格式如下:
+
+
+
+
+
+## 5.5 常见响应报文头部属性
+
+- Cache-Control
+ - 响应输出到客户端后,服务端通过该属性告诉客户端该怎么控制响应内容的缓存
+- ETag
+ - 表示客户端请求资源的版本,如果该资源发生了变化,那么这个属性也会跟着变
+- Location
+ - 在重定向中或者创建新资源时使用
+- Set-Cookie
+ - 服务端可以设置客户端的 cookie
+
+# 6. HTTP 状态码
+
+- 状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:
+ - 1xx:指示信息--表示请求已接收,继续处理
+ - 2xx:成功--表示请求已被成功接收、理解、接受
+ - 3xx:重定向--要完成请求必须进行更进一步的操作
+ - 4xx:客户端错误--请求有语法错误或请求无法实现
+ - 5xx:服务器端错误--服务器未能实现合法的请求
+- 常见状态码
+
+```xml
+200 OK //客户端请求成功
+400 Bad Request //客户端请求有语法错误,不能被服务器所理解
+401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
+403 Forbidden //服务器收到请求,但是拒绝提供服务
+404 Not Found //请求资源不存在,eg:输入了错误的URL
+500 Internal Server Error //服务器发生不可预期的错误
+503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
+```
+
+
+# 7. HTTP 请求方法
+
+根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
+
+HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
+
+HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
+
+- GET:请求指定的页面信息,并返回实体主体。
+- HEAD:类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头
+- POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
+- PUT:从客户端向服务器传送的数据取代指定的文档的内容。
+- DELETE:请求服务器删除指定的页面。
+- CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
+- OPTIONS:允许客户端查看服务器的性能。
+- TRACE:回显服务器收到的请求,主要用于测试或诊断。
+
+
+# 8. 长连接与短连接
+
+HTTP1.1 规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。
+
+在实际使用中,HTTP 头部有了 Keep-Alive 这个值并不代表一定会使用长连接,客户端和服务器端都可以无视这个值,也就是不按标准来。毕竟 TCP 是一个双向连接的协议,双方都可以决定是不是主动断开。
+
+客户端的长连接不可能无限期的拿着,会有一个超时时间,服务器有时候会告诉客户端超时时间。下图中的 Keep-Alive: timeout=20,表示这个TCP通道可以保持20秒
+
+
+
+# 9. 课后作业
+
+- [扩展]了解更多请求/响应报文头属性
+- [扩展]了解更多响应状态码
+
diff --git a/02.企业服务/03.HTTP协议/CS架构.png b/02.企业服务/03.HTTP协议/CS架构.png
new file mode 100644
index 0000000..96be4c0
Binary files /dev/null and b/02.企业服务/03.HTTP协议/CS架构.png differ
diff --git a/02.企业服务/03.HTTP协议/Keep-Alive报文.png b/02.企业服务/03.HTTP协议/Keep-Alive报文.png
new file mode 100644
index 0000000..8872372
Binary files /dev/null and b/02.企业服务/03.HTTP协议/Keep-Alive报文.png differ
diff --git a/02.企业服务/03.HTTP协议/响应报文格式.png b/02.企业服务/03.HTTP协议/响应报文格式.png
new file mode 100644
index 0000000..077803e
Binary files /dev/null and b/02.企业服务/03.HTTP协议/响应报文格式.png differ
diff --git a/02.企业服务/03.HTTP协议/响应报文示例.png b/02.企业服务/03.HTTP协议/响应报文示例.png
new file mode 100644
index 0000000..1c67422
Binary files /dev/null and b/02.企业服务/03.HTTP协议/响应报文示例.png differ
diff --git a/02.企业服务/03.HTTP协议/请求报文格式.png b/02.企业服务/03.HTTP协议/请求报文格式.png
new file mode 100644
index 0000000..204aa70
Binary files /dev/null and b/02.企业服务/03.HTTP协议/请求报文格式.png differ
diff --git a/02.企业服务/03.HTTP协议/请求报文示例.png b/02.企业服务/03.HTTP协议/请求报文示例.png
new file mode 100644
index 0000000..c867a24
Binary files /dev/null and b/02.企业服务/03.HTTP协议/请求报文示例.png differ
diff --git a/02.企业服务/04.Apache.md b/02.企业服务/04.Apache.md
new file mode 100644
index 0000000..4d8a17d
--- /dev/null
+++ b/02.企业服务/04.Apache.md
@@ -0,0 +1,1592 @@
+# 1. 常用的网站服务软件
+
+- 曾经Apache是第一,虽然现在不是,但是在行业中依旧非常的常见
+- [https://w3techs.com/technologies/overview/web_server](https://w3techs.com/technologies/overview/web_server)
+
+
+
+**Apache是什么**
+
+Apache HTTP Server简称为 Apache,是 Apache 软件基金会的一个高性能、功能强大、见状可靠、又灵活的开放源代码的web服务软件,它可以运行在广泛的计算机平台上如 Linux、Windows。因其平台型和很好的安全性而被广泛使用,是互联网最流行的 web 服务软件之一。
+
+**特点**
+
+- 功能强大
+- 高度模块化
+- 采用MPM多路处理模块
+- 配置简单
+- 速度快
+- 应用广泛
+- 性能稳定可靠
+- 可做代理服务器或负载均衡来使用
+- 双向认证
+- 支持第三方模块
+
+**应用场景**
+
+- 使用Apache运行静态HTML网页、图片
+- 使用Apache结合PHP、Linux、MySQL可以组成LAMP经典架构
+- 使用Apache作代理、负载均衡等
+
+**MPM工作模式**
+
+- prefork:多进程I/O模型,一个主进程,管理多个子进程,一个子进程处理一个请求。
+- worker:复用的多进程I/O模型,多进程多线程,一个主进程,管理多个子进程,一个子进程管理多个线程,每个线程处理一个请求。
+- event:事件驱动模型,一个主进程,管理多个子进程,一个进程处理多个请求。
+
+# 2. Apache 基础
+
+## 2.1 安装部署
+
+RockyLinux 软件仓库中存在此软件包,可以直接通过 yum 进行安装
+
+```shell
+[root@localhost ~]# yum -y install httpd
+[root@localhost ~]# systemctl start httpd && systemctl enable httpd
+[root@localhost ~]# httpd -v
+Server version: Apache/2.4.62 (Rocky Linux)
+Server built: Jan 29 2025 00:00:00
+
+# 使用 curl 或者浏览器测试网页是否正常
+[root@localhost ~]# echo "Hello World!" > /var/www/html/index.html
+[root@localhost ~]# curl -I 127.0.0.1
+HTTP/1.1 200 OK
+```
+
+## 2.2 httpd 命令
+
+httpd 为 Apache HTTP 服务软件的命令
+
+```shell
+[root@localhost ~]# httpd -h
+Usage: httpd [-D name] [-d Directory] [-f file]
+ [-C "directive"] [-c "directive"]
+ [-k start|restart|graceful|graceful-stop|stop]
+ [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
+```
+
+**常用选项**
+
+| 选项 | 说明 |
+| :---------------- | :----------------------------------- |
+| -c
+
+## 14.1 安装Apache
+
+```bash
+[root@localhost ~]# yum install -y httpd
+
+# 启动httpd
+[root@localhost ~]# systemctl enable --now httpd
+
+# 关闭防火墙和SElinux
+[root@localhost ~]# systemctl stop firewalld
+[root@localhost ~]# setenforce 0
+```
+
+**访问测试:**`http://IP`
+
+
+
+## 14.2 安装php环境
+
+1. 安装php8.0全家桶
+
+```bash
+[root@localhost ~]# yum install -y php*
+
+# 启动php-fpm
+[root@localhost ~]# systemctl enable --now php-fpm
+[root@localhost ~]# systemctl status php-fpm
+● php-fpm.service - The PHP FastCGI Process Manager
+ Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
+ Active: active (running) since Sat 2025-01-18 21:54:09 CST; 7s ago
+ Main PID: 34564 (php-fpm)
+ Status: "Ready to handle connections"
+ Tasks: 6 (limit: 10888)
+ Memory: 22.6M
+ CPU: 119ms
+ CGroup: /system.slice/php-fpm.service
+ ├─34564 "php-fpm: master process (/etc/php-fpm.conf)"
+ ├─34565 "php-fpm: pool www"
+ ├─34566 "php-fpm: pool www"
+ ├─34567 "php-fpm: pool www"
+ ├─34568 "php-fpm: pool www"
+ └─34569 "php-fpm: pool www"
+
+Jan 18 21:54:09 localhost.localdomain systemd[1]: Starting The PHP FastCGI Process Manage>
+Jan 18 21:54:09 localhost.localdomain systemd[1]: Started The PHP FastCGI Process Manager.
+```
+
+2. 重启httpd服务以加载php相关模块
+
+```bash
+[root@localhost ~]# systemctl restart httpd
+```
+
+## 14.3 安装Mysql数据库
+
+```bash
+# 安装mariadb数据库软件
+[root@localhost ~]# yum install -y mariadb-server mariadb
+
+# 启动数据库并且设置开机自启动
+[root@localhost ~]# systemctl enable --now mariadb
+
+# 设置mariadb的密码
+[root@localhost ~]# mysqladmin password '123456'
+
+# 验证数据库是否工作正常
+[root@localhost ~]# mysql -uroot -p123456 -e "show databases;"
++--------------------+
+| Database |
++--------------------+
+| information_schema |
+| mysql |
+| performance_schema |
++--------------------+
+```
+
+## 14.4 PHP探针测试
+
+在默认的网站根目录下创建`info.php`
+
+```bash
+[root@localhost ~]# vim /var/www/html/info.php
+
+```
+
+写一个简单的php代码,可以使用phpinfo函数查看php的信息,从而检测是否成功解析php代码
+
+编写好以后,我们访问:`http://IP/info.php`测试
+
+
+
+这里如果可以看到上述页面,说明我们的php代码成功被解析了
+
+## 14.5 数据库连接测试
+
+编写php代码,用php来连接数据库测试
+
+```bash
+[root@localhost ~]# vim /var/www/html/mysql.php
+
+```
+
+编写好以后,我们访问:`http://IP/mysql.php`测试:
+
+
+
+## 14.6 安装phpmyadmin
+
+由于我们还没有学习mysql如何管理,我们可以部署phpmyadmin工具,该工具可以让我们可视化管理我们的数据库
+
+```bash
+# 移动到网站根目录
+[root@localhost ~]# cd /var/www/html
+
+# 下载phpmyadmin源码
+[root@localhost ~]# wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip
+
+# 解压软件包,并且重命名
+[root@localhost ~]# unzip phpMyAdmin-5.1.1-all-languages.zip
+[root@localhost ~]# mv phpMyAdmin-5.1.1-all-languages phpmyadmin
+```
+
+访问`http://IP/phpmyadmin`进行测试
+
+
+
+用户名和密码为我们刚才初始化数据库时设置的root和123456,登陆后,会进入图形化管理界面
+
+
+
+# 15. 个人博客
+
+## 15.1 源码获取
+
+下载typecho博客系统源码到`/var/www/html/typecho`
+
+```bash
+[root@localhost ~]# cd /var/www/html
+
+# 创建typecho目录
+[root@localhost ~]# mkdir typecho
+[root@localhost ~]# cd typecho
+
+[root@localhost ~]# wget https://github.com/typecho/typecho/releases/latest/download/typecho.zip
+
+# 解压源码
+[root@localhost ~]# unzip typecho.zip
+```
+
+## 15.2 创建数据库
+
+点击数据库
+
+
+
+输入数据库名之后,就可以点击创建
+
+
+
+## 15.3 安装博客系统
+
+下面就可以开始进入网站安装的部分了,访问博客系统页面
+
+`http://IP/typecho`
+
+
+
+提示安装目录下面的/usr/uploads没有权限,那么我们手动赋予该目录w权限
+
+```bash
+[root@localhost typecho]# chmod a+w usr/uploads/
+```
+
+填写数据库信息,密码为部署mariadb时设置的123456
+
+
+
+遇到提示无法自动创建配置文件config.inc.php。我们手动在网站的根目录下创建该文件,并且将内容复制进去
+
+```bash
+[root@localhost typecho]# vim config.inc.php
+```
+
+之后完善如下网站信息后,点击继续安装
+
+
+
+到此,我们的typecho个人博客系统就部署完成了
+
+
+
+## 15.4 切换主题
+
+默认的主题如下,界面比较的简洁,我们可以给这个网站替换主题,也可以借此加深熟悉我们对Linux命令行的熟练程度
+
+
+
+第三方主题商店:https://www.typechx.com/
+
+我们尝试更换这个主题
+
+
+
+选择模板下载
+
+
+
+然后在打开的github仓库中下载ZIP压缩包
+
+
+
+将下载好的主题压缩包上传到博客主题的目录`/var/www/html/typecho/usr/themes`
+
+
+
+然后解压主题包,并且将名称改为简单一点的
+
+```bash
+[root@localhost themes]# unzip Typecho-Butterfly-main.zip
+[root@localhost themes]# ls
+Typecho-Butterfly-main Typecho-Butterfly-main.zip default
+[root@localhost themes]# mv Typecho-Butterfly-main butterfly
+[root@localhost themes]# rm -rf Typecho-Butterfly-main.zip
+```
+
+然后登录到博客后台,在设置里更换主题
+
+
+
+然后回到博客首页刷新一下,就可以看到新的主题已经应用了~
+
+
+
+会有一些图片资源的丢失,稍微了解一点前端知识,就可以将其完善好了。不懂前端的同学,可以去找一些简单一点的主题。
+
+
\ No newline at end of file
diff --git a/02.企业服务/04.Apache/HTTPS请求过程.png b/02.企业服务/04.Apache/HTTPS请求过程.png
new file mode 100644
index 0000000..b44cdfc
Binary files /dev/null and b/02.企业服务/04.Apache/HTTPS请求过程.png differ
diff --git a/02.企业服务/04.Apache/LAMP架构.png b/02.企业服务/04.Apache/LAMP架构.png
new file mode 100644
index 0000000..66042cb
Binary files /dev/null and b/02.企业服务/04.Apache/LAMP架构.png differ
diff --git a/02.企业服务/04.Apache/event工作模式.png b/02.企业服务/04.Apache/event工作模式.png
new file mode 100644
index 0000000..b70b836
Binary files /dev/null and b/02.企业服务/04.Apache/event工作模式.png differ
diff --git a/02.企业服务/04.Apache/image-20211106110832539.png b/02.企业服务/04.Apache/image-20211106110832539.png
new file mode 100644
index 0000000..d79cec3
Binary files /dev/null and b/02.企业服务/04.Apache/image-20211106110832539.png differ
diff --git a/02.企业服务/04.Apache/image-20240719230216883.png b/02.企业服务/04.Apache/image-20240719230216883.png
new file mode 100644
index 0000000..e86a4e8
Binary files /dev/null and b/02.企业服务/04.Apache/image-20240719230216883.png differ
diff --git a/02.企业服务/04.Apache/image-20240719231237537.png b/02.企业服务/04.Apache/image-20240719231237537.png
new file mode 100644
index 0000000..a2ce59f
Binary files /dev/null and b/02.企业服务/04.Apache/image-20240719231237537.png differ
diff --git a/02.企业服务/04.Apache/image-20240719231636758.png b/02.企业服务/04.Apache/image-20240719231636758.png
new file mode 100644
index 0000000..6d0f345
Binary files /dev/null and b/02.企业服务/04.Apache/image-20240719231636758.png differ
diff --git a/02.企业服务/04.Apache/image-20240719231744450.png b/02.企业服务/04.Apache/image-20240719231744450.png
new file mode 100644
index 0000000..4fc6bb6
Binary files /dev/null and b/02.企业服务/04.Apache/image-20240719231744450.png differ
diff --git a/02.企业服务/04.Apache/image-20240719232259490.png b/02.企业服务/04.Apache/image-20240719232259490.png
new file mode 100644
index 0000000..4594ff6
Binary files /dev/null and b/02.企业服务/04.Apache/image-20240719232259490.png differ
diff --git a/02.企业服务/04.Apache/image-20250118215910240.png b/02.企业服务/04.Apache/image-20250118215910240.png
new file mode 100644
index 0000000..668ff83
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118215910240.png differ
diff --git a/02.企业服务/04.Apache/image-20250118220523743.png b/02.企业服务/04.Apache/image-20250118220523743.png
new file mode 100644
index 0000000..5760ce9
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118220523743.png differ
diff --git a/02.企业服务/04.Apache/image-20250118220724260.png b/02.企业服务/04.Apache/image-20250118220724260.png
new file mode 100644
index 0000000..29d0a8b
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118220724260.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221026614.png b/02.企业服务/04.Apache/image-20250118221026614.png
new file mode 100644
index 0000000..3c86d6b
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221026614.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221109186.png b/02.企业服务/04.Apache/image-20250118221109186.png
new file mode 100644
index 0000000..0521f31
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221109186.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221202018.png b/02.企业服务/04.Apache/image-20250118221202018.png
new file mode 100644
index 0000000..9c04f14
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221202018.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221344667.png b/02.企业服务/04.Apache/image-20250118221344667.png
new file mode 100644
index 0000000..cd68b8d
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221344667.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221414487.png b/02.企业服务/04.Apache/image-20250118221414487.png
new file mode 100644
index 0000000..39da26f
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221414487.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221502963.png b/02.企业服务/04.Apache/image-20250118221502963.png
new file mode 100644
index 0000000..4b009f7
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221502963.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221634385.png b/02.企业服务/04.Apache/image-20250118221634385.png
new file mode 100644
index 0000000..4da4c1a
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221634385.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221843976.png b/02.企业服务/04.Apache/image-20250118221843976.png
new file mode 100644
index 0000000..e1d1783
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221843976.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221920089.png b/02.企业服务/04.Apache/image-20250118221920089.png
new file mode 100644
index 0000000..6d7a0e1
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221920089.png differ
diff --git a/02.企业服务/04.Apache/image-20250118221958932-1763003655010-58.png b/02.企业服务/04.Apache/image-20250118221958932-1763003655010-58.png
new file mode 100644
index 0000000..2ae3a7f
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118221958932-1763003655010-58.png differ
diff --git a/02.企业服务/04.Apache/image-20250118224232388.png b/02.企业服务/04.Apache/image-20250118224232388.png
new file mode 100644
index 0000000..f274f01
Binary files /dev/null and b/02.企业服务/04.Apache/image-20250118224232388.png differ
diff --git a/02.企业服务/04.Apache/prefork模式.png b/02.企业服务/04.Apache/prefork模式.png
new file mode 100644
index 0000000..d417fa1
Binary files /dev/null and b/02.企业服务/04.Apache/prefork模式.png differ
diff --git a/02.企业服务/04.Apache/web_server_top.png b/02.企业服务/04.Apache/web_server_top.png
new file mode 100644
index 0000000..411b16f
Binary files /dev/null and b/02.企业服务/04.Apache/web_server_top.png differ
diff --git a/02.企业服务/04.Apache/worker工作模式.png b/02.企业服务/04.Apache/worker工作模式.png
new file mode 100644
index 0000000..495e6b2
Binary files /dev/null and b/02.企业服务/04.Apache/worker工作模式.png differ
diff --git a/02.企业服务/05.Nginx.md b/02.企业服务/05.Nginx.md
new file mode 100644
index 0000000..a6456f5
--- /dev/null
+++ b/02.企业服务/05.Nginx.md
@@ -0,0 +1,1690 @@
+# 1. Nginx 介绍
+
+Nginx:engine X ,2002年开始开发,2004年开源,2019年3⽉11⽇,Nginx公司被F5 Networks以6.7亿美元收购。
+
+Nginx 则是免费的、开源的、⾼性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器 解决[C10K问题](https://www.ideawu.net/blog/archives/740.html)(10K Connections)
+
+**Nginx官网:** http://nginx.org/
+
+**Nginx 商业版为 Nginx Plus:** https://www.nginx.com/products/nginx/
+
+**Nginx ⼆次发行版:**
+
+- Tengine:由淘宝⽹发起的Web服务器项⽬。它在Nginx的基础上,针对⼤访问量⽹站的需求,添加了很多⾼级功能和特性。Tengine的性能和稳定性已经在⼤型的⽹站如淘宝⽹,天猫商城等得到了很好的检验。它的最终⽬标是打造⼀个⾼效、稳定、安全、易⽤的Web平台,从2011年12⽉开始,Tengine成为⼀个开源项⽬,官⽹ http://tengine.taobao.org/
+- OpenResty:基于 Nginx 与 Lua 语⾔的⾼性能 Web 平台, 章亦春团队开发,官⽹ http://openresty.org/cn/
+
+## 1.1 功能
+
+- 静态的web资源服务器 html,image,js,css,txt 等静态资源
+- 结合 FastCGI/uWSGI/SCGI 等协议反向代理动态资源请求
+- http/https 协议的反向代理
+- imap4/pop3 协议的反向代理
+- tcp/udp 协议的反向代理
+
+## 1.2 基本特征
+
+- 模块化设计,较好的扩展性
+- ⾼可靠性高性能高于 apache
+- ⽀持热部署:不停机更新配置⽂件,升级版本,更换⽇志⽂件
+- 低内存消耗:10000个 keep-alive 连接模式下的⾮活动连接,仅需2.5M内存
+- 事件驱动epoll,异步非阻塞IO,内存映射等等特性
+
+
+# 2. Nginx 基础
+
+## 2.1 安装部署
+
+Nginx 版本分为 Mainline version(主要开发版本)、Stable version (当前最新稳定版)、Legacy versions (旧的稳定版)
+
+**官方下载地址:** http://nginx.org/en/download.html
+
+对于 Nginx 的安装,我们常用的方法为在线安装和源码包编译安装
+
+**其中:**
+
+- yum 下载的相关文件都是放在默认的位置,简单高效
+- 编译安装可以自定义版本和功能,更适合业务的定制化
+
+**YUM 安装**
+
+```shell
+# 安装
+[root@localhost ~]# yum provides nginx
+[root@localhost ~]# yum install nginx -y
+# 启动
+[root@localhost ~]# systemctl start nginx && systemctl enable nginx
+# 关闭防火墙和SELINUX
+# 测试
+[root@localhost ~]# curl -I 127.0.0.1
+HTTP/1.1 200 OK
+Server: nginx/1.20.1
+
+```
+
+**编译安装**
+
+```shell
+# 准备编译环境
+[root@localhost ~]# yum -y install gcc pcre-devel openssl-devel zlib-devel
+# 如果需要编译安装,为避免冲突需要将yum部署的nginx版本先卸载掉!
+# 准备源码包
+[root@localhost ~]# wget http://nginx.org/download/nginx-1.22.0.tar.gz -P /usr/local/src/
+[root@localhost ~]# cd /usr/local/src && tar xzvf nginx-1.22.0.tar.gz
+# 编译
+[root@localhost ~]# useradd -r -s /sbin/nologin nginx
+[root@localhost nginx-1.22.0]# ./configure --prefix=/apps/nginx \
+ --user=nginx \
+ --group=nginx \
+ --with-http_ssl_module \
+ --with-http_v2_module \
+ --with-http_realip_module \
+ --with-http_stub_status_module \
+ --with-http_gzip_static_module \
+ --with-pcre \
+ --with-stream \
+ --with-stream_ssl_module \
+ --with-stream_realip_module \
+ --with-file-aio
+[root@localhost nginx-1.22.0]# make -j 2 && make install
+# 善后工作
+[root@localhost nginx-1.22.0]# chown -R nginx.nginx /apps/nginx
+[root@localhost nginx-1.22.0]# ln -s /apps/nginx/sbin/nginx /usr/sbin/
+[root@localhost nginx-1.22.0]# nginx -v
+# systemd管理
+[root@localhost ~]# cat << EOF > /usr/lib/systemd/system/nginx.service
+[Unit]
+Description=The nginx HTTP and reverse proxy server
+Documentation=http://nginx.org/en/docs/
+After=network.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/apps/nginx/run/nginx.pid
+ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
+ExecReload=/bin/kill -s HUP $MAINPID
+ExecStop=/bin/kill -s TERM $MAINPID
+
+[Install]
+WantedBy=multi-user.target
+EOF
+# 更新nginx.pid存储位置
+[root@localhost ~]# mkdir /apps/nginx/run/
+[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
+pid /apps/nginx/run/nginx.pid;
+# 启动
+[root@localhost ~]# systemctl start nginx && systemctl enable nginx
+# 关闭防火墙和SELINUX
+[root@localhost ~]# curl -I 127.0.0.1
+HTTP/1.1 200 OK
+Server: nginx/1.22.0
+
+```
+
+## 2.2 nginx 命令
+
+nginx 为 Nginx 服务软件的命令
+
+```shell
+[root@localhost ~]# nginx -h
+nginx version: nginx/1.20.1
+Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
+ [-e filename] [-c filename] [-g directives]
+```
+
+**常用选项**
+
+| 选项 | 说明 |
+| :---------- | :----------------------- |
+| -v | 输出版本 |
+| -V | 编译相关选项 |
+| -t | 测试验证配置文件的正确性 |
+| -s
+
+- Active connections: 2 表示Nginx正在处理的活动连接数2个。
+- server 2 表示Nginx启动到现在共处理了2个连接
+- accepts 2 表示Nginx启动到现在共成功创建2次握手
+- handled requests 1 表示总共处理了 1 次请求
+- Reading:Nginx 读取到客户端的 Header 信息数,数值越大,说明排队越长,性能不足
+- Writing:Nginx 返回给客户端 Header 信息数,数值越大,说明访问量越大
+- Waiting:Nginx 已经处理完正在等候下一次请求指令的驻留链接(开启keep-alive的情况下,这个值等于Active-(Reading+Writing))
+
+
+## 10.7 其他
+
+- 对哪种浏览器禁用长连接
+
+```shell
+keepalive_disable none | browser ...;
+```
+
+- 限制客户端使用除了指定的请求方法之外的其他方法
+
+```shell
+limit_except method ... { ... }; # 仅用于location
+method: GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
+[root@localhost conf.d]# vim /apps/nginx/conf.d/www.conf
+location /download {
+ root /apps/nginx/html/www;
+ autoindex on;
+ autoindex_exact_size off;
+ autoindex_localtime on;
+ limit_except POST { #相当于只允许底下允许列表里的使用除了post外的其他方法
+ allow 192.168.112.1; #只有浏览器可以使用除了post外的其他方法(get delete),其他人只能用post
+ deny all;
+}
+}
+[root@localhost conf.d]# systemctl restart nginx
+
+
+# 观察现象
+curl file.test.com/download
+curl file.test.com/download -X POST -d "hello"
+两次报错不一致,一个403一个404
+
+cd /apps/nginx/html/www
+touch f1
+touch f2
+vim /apps/nginx/conf.d/www.conf
+
+将 root /apps/nginx/html/www;改成 alias /apps/nginx/html/www;
+浏览器测试 http://file.test.com/download/,能否访问到get请求
+```
+
+- 是否启用asynchronous file I/O(AIO)功能,需要编译开启`--with-file-aio`
+- 在读取文件的时候使用异步可以提高效率
+
+```shell
+aio on | off;
+```
+
+```shell
+[root@localhost nginx-1.22.0]# cd /usr/local/src/nginx-1.22.0
+[root@localhost nginx-1.22.0]# ./configure --prefix=/apps/nginx \
+--user=nginx \
+--group=nginx \
+--with-http_ssl_module \
+--with-http_v2_module \
+--with-http_realip_module \
+--with-http_stub_status_module \
+--with-http_gzip_static_module \
+--with-pcre \
+--with-stream \
+--with-stream_ssl_module \
+--with-stream_realip_module \
+--with-file-aio
+[root@localhost nginx-1.22.0]# make -j 2 && make install
+[root@localhost nginx-1.22.0]# nginx -V
+nginx version: slsnginx/1.22.0
+built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
+built with OpenSSL 1.0.2k-fips 26 Jan 2017
+TLS SNI support enabled
+configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --with-file-aio
+#支持file-aio了
+[root@localhost nginx-1.22.0]# vim /apps/nginx/conf.d/www.conf
+server {
+ listen 80;
+ server_name file.test.com;
+ aio on;
+...
+}
+```
+
+- directio是在写文件到磁盘的时候大小大于size的时候,直接写磁盘,而非写缓存
+
+```shell
+directio size | off;
+```
+
+- Nginx支持对磁盘中的文件进行缓存
+
+```shell
+open_file_cache on; # 是否缓存打开过的文件信息
+open_file_cache max=N [inactive=time];
+#nginx可以缓存以下三种信息:
+#1. 文件元数据,文件的描述符,文件大小和最近一次的修改时间
+#2. 打开的目录结构
+#3. 没有找到的或者没有权限访问的文件相关信息
+max=N; # 可缓存的缓存项上限数量;达到上限后会使用LRU(Least recently used,最近最少使用)算法实现管理
+inactive=time; # 缓存项的非活动时长,在此处指定的时长内未被命中的或命中的次数少于open_file_cache_min_uses指令所指定的次数的缓存项即为非活动项,将被删除
+open_file_cache_valid time; #缓存项有效性的检查验证频率,默认值为60s
+open_file_cache_errors on | off; #是否缓存查找时发生错误的文件一类的信息,默认值为off
+open_file_cache_min_uses number; # open_file_cache指令的inactive参数指定的时长内,至少被命中此处指定的次数方可被归类为活动项,默认值为1
+```
+
+范例:
+
+```shell
+open_file_cache max=10000 inactive=60s;
+open_file_cache_vaild 60s;
+open_file_cache_min_uses 5;
+open_file_cache_errors off;
+```
+
+
+# 11. HTTPS 功能
+
+Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成: HTTP + SSL/ TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
+
+
+## 11.1 配置参数
+
+nginx的https功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssI功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启
+
+官方文档:https://nginx.org/en/docs/http/ngx_http_ssl_module.html
+
+配置参数如下:
+
+```shell
+ssl on | off;
+listen 443 ssl;
+# 为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代。
+ssl_certificate /path/to/file;
+# 当前虚拟主机使用使用的公钥文件,一般是crt文件
+ssl_certificate_key /path/to/file;
+# 当前虚拟主机使用的私钥文件,一般是key文件
+ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
+# 支持ssl协议版本,早期为ssl现在是TSL,默认为后三个
+ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
+# 配置ssl缓存
+ off:
+ # 关闭缓存
+ none:
+ # 通知客户端支持ssl session cache,但实际不支持
+ builtin[:size]:
+ # 使用OpenSSL内建缓存,为每worker进程私有
+ [shared:name:size]:
+ # 在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称。
+ssl_session_timeout time;
+# 客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
+```
+
+## 11.2 自签名证书
+
+- 生成ca证书
+
+```shell
+[root@localhost ~]# cd /apps/nginx
+[root@localhost nginx]# mkdir certs && cd certs
+[root@localhost certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
+```
+
+- 生成证书请求文件
+
+```shell
+[root@localhost certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout iproute.cn.key -out iproute.cn.csr
+```
+
+- 签发证书
+
+```shell
+[root@localhost certs]# openssl x509 -req -days 36500 -in iproute.cn.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out iproute.cn.crt
+[root@localhost certs]# cat iproute.cn.crt ca.crt > iproute.crt
+```
+
+- 验证证书内容
+
+```shell
+[root@localhost certs]# openssl x509 -in iproute.cn.crt -noout -text
+```
+
+## 11.3 证书配置
+
+```shell
+[root@localhost certs]# vim /apps/nginx/conf.d/ssl.conf
+server {
+ listen 80;
+ listen 443 ssl;
+ ssl_certificate /apps/nginx/certs/iproute.crt;
+ ssl_certificate_key /apps/nginx/certs/iproute.cn.key;
+ ssl_session_cache shared:sslcache:20m;
+ ssl_session_timeout 10m;
+ root /apps/nginx/html;
+}
+```
+
+## 11.4 测试验证
+
+
+
+# 12. Nginx 架构和进程
+
+## 12.1 Nginx 架构
+
+Nginx 采用了 master-worker 架构,由 master 进程负责通信和调度,worker 进程响应具体的请求
+
+
+
+## 12.2 Nginx 进程模型
+
+Nginx 的进程模型是其高性能和高并发的核心,采用多进程架构(默认模式),主要由 Master 进程和多个 Worker 进程组成,结合**异步非阻塞 I/O 模型**实现高效请求处理
+
+
+
+**Master 进程:**
+
+- 对外接口:接收外部的操作(信号)
+- 对内转发:根据外部的操作的不同,通过信号管理 worker
+- 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
+- 配置加载:读取 Nginx 配置文件并验证其有效性和正确性
+- 管理连接:建立、绑定和关闭 socket 连接
+- 按照配置生成、管理和结束工作进程
+- 接受外界指令,比如重启、升级及退出服务器等指令
+- 不中断服务,实现平滑升级,重启服务并应用新的配置
+- 开启日志文件,获取文件描述符
+- 不中断服务,实现平滑升级,升级失败进行回滚处理
+
+**Worker 进程:**
+
+- 所有 Worker 进程都是平等的,接受处理客户的请求
+- 实际处理:网络请求,由 Worker 进程处理
+- Worker进程数量:在nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。
+- 将请求依次送入各个功能模块进行处理
+- I/O调用,获取响应数据
+- 与后端服务器通信,接收后端服务器的处理结果
+- 缓存数据,访问缓存索引,查询和调用缓存数据
+- 发送请求结果,响应客户的请求
+- 接收主程序指令,比如重启、升级和退出等
+
+**工作细节**
+
+
+
+
+
+## 12.3 Nginx 进程间通信
+
+**图示如下**
+
+
+
+**信号**:Master 进程通过信号控制 Worker 进程的生命周期及配置更新,典型场景:SIGHUP(重新加载配置文件)、SIGTERM(优雅关闭 Worker 进程)、SIGUSR1(重新打开日志文件)
+**管道**:Master 进程与 Worker 进程之间单向传递指令,Master 进程传递 Worker ID、指令、索引、文件描述符等等,Worker 进程监听管道事件并执行具体事项
+**共享内存**:Worker 进程间共享数据,典型场景:限流计数、缓存状态等等
+
+## 12.4 HTTP 请求处理流程
+
+**图示如下**
+
+
+
+# 13. 性能优化
+
+
+## 13.1 CPU性能相关
+
+```bash
+user nginx nginx; #启动Nginx工作进程的用户和组
+worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
+worker_cpu_affinity 0001 0010 0100 1000; # 将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占一核心CPU,但是可以保障此进程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了cpu对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
+CPU MASK:0001 0号CPU
+ 0010 1号CPU
+ 0100 2号CPU
+ 1000 3号CPU
+[root@localhost ~]# watch -n.5 'ps axo pid,cmd,psr |grep nginx'
+# 查看nginx进程对应的CPU
+ 6834 nginx: master process /apps 2
+ 47621 nginx: worker process 0
+ 47622 nginx: worker process 1
+ 47623 nginx: worker process 2
+ 47624 nginx: worker process 3
+[root@localhost ~]# while true;do ab -c 1000 -n 2000 http://127.0.0.1/;done
+# 压力测试 要先yum -y install httpd-tools
+```
+
+**案例分析**
+
+修改 cpu 数量
+
+1. 使用top命令查看虚拟机中cpu的核心数
+
+
+
+2. 修改nginx.conf,在全局配置中增加对cpu的控制字段
+
+```bash
+[root@localhost nginx-1.22.0]# vim /apps/nginx/conf/nginx.conf
+#user nobody;
+worker_processes 4;
+worker_cpu_affinity 0001 0010 0100 1000;
+
+# 这里配置的时候,注意自己虚拟机上cpu的数量,不要超过自己虚拟机cpu核心数
+
+#重载配置
+[root@localhost nginx-1.22.0]# nginx -t
+[root@localhost nginx-1.22.0]# systemctl restart nginx
+```
+
+3. 查看nginx进程所使用对应的cpu
+
+```bash
+[root@localhost nginx-1.22.0]# watch -n.5 'ps axo pid,cmd,psr |grep nginx'
+# 查看nginx进程对应的CPU
+ 6834 nginx: master process /apps 2
+ 47621 nginx: worker process 0
+ 47622 nginx: worker process 1
+ 47623 nginx: worker process 2
+ 47624 nginx: worker process 3
+```
+
+## 13.2 工作优先级与文件并发数
+
+```shell
+worker_priority 0; #工作进程优先级(-20~19)
+worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上线,包括:Nginx的所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件数的限制,最好与ulimit -n的值保持一致
+[root@localhost ~]# vim /etc/security/limits.conf
+* soft nofile 102400
+* hard nofile 102400
+
+
+# 案例-修改优先级
+root@localhost nginx-1.22.0]# vim /apps/nginx/conf/nginx.conf
+worker_priority -20;
+
+#重载配置
+[root@localhost nginx-1.22.0]# nginx -t
+[root@localhost nginx-1.22.0]# systemctl restart nginx
+
+# 查看优先级
+[root@localhost ~]# watch -n.5 'ps axo pid,cmd,psr,nice |grep nginx'
+Every 0.5s: ps axo pid,cmd,psr,nice |grep nginx Mon Jul 15 08:11:44 2024
+
+ 22950 nginx: master process /apps 1 0
+ 22951 nginx: worker process 0 -20
+ 22952 nginx: worker process 1 -20
+ 22953 nginx: worker process 2 -20
+ 22954 nginx: worker process 3 -20
+ 23004 grep nginx 3 0
+```
+
+## 13.3 其他优化配置
+
+```shell
+daemon off; # 前台运行nginx服务,用于测试、docker等环境
+master_process off|on; # 是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为on
+events {
+ worker_connections 65536; # 设置单个工作进程的最大并发连接数
+ use epoll; # 使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、epoll,只能设置在events模块中
+ accept_mutex on; # on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也被称为"惊群",因此nginx刚安装完以后要进行适当的优化,建议设置为on
+ multi_accept on; # on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个,建议设置为on
+}
+```
+
+- 默认配置并不支持高并发,在压力测试下会报错
+
+```shell
+[root@localhost ~]# yum install -y httpd-tools
+[root@localhost ~]# while true;do ab -c 1000 -n 10000 http://127.0.0.1/;sleep 0.5;done
+
+[root@localhost ~]# tail /apps/nginx/logs/error.log
+2021/05/24 12:35:53 [crit] 6828#0: *10996 open() "/apps/nginx/html/index.html" failed (24: Too many open files), client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "127.0.0.1"
+2021/05/24 12:35:53 [crit] 6828#0: *10996 open() "/apps/nginx/html/50x.html" failed (24: Too many open files), client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "127.0.0.1"
+
+[root@localhost ~]# vim /etc/security/limits.conf
+* - nproc 100000
+[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
+worker_rlimit_nofile 65536;
+events {
+ worker_connections 10240;
+}
+[root@localhost ~]# systemctl restart nginx
+```
+
+
+# 14. LNMP 架构概述
+
+LNMP是一套技术的组合,L=Linux、N=Nginx、M=MySQL、P=PHP
+
+## 14.1 如何工作
+
+- 首先 nginx 服务是不能处理动态请求,那么当用户发起动态请求时,nginx 无法处理
+- 当用户发起 http 请求,请求会被 nginx 处理,如果是静态资源请求 nginx 则直接返回,如果是动态请求 nginx 则通过 fastcgi 协议转交给后端的 PHP 程序处理
+
+
+
+## 14.2 工作流程
+
+
+
+1. 用户通过 http 协议发起请求,请求会先抵达 LNM P架构中的nginx
+2. nginx 会根据用户的请求进行location规则匹配
+3. location 如果匹配到请求是静态,则由 nginx 读取本地直接返回
+4. location 如果匹配到请求是动态,则由 nginx 将请求转发给 fastcgi 协议
+5. fastcgi 收到请求交给 php-fpm 管理进程,php-fpm 管理进程接收到后会调用具体的工作进程 wrapper
+6. wrapper 进程会调用 PHP 程序进行解析,如果只是解析代码,php 直接返回
+7. 如果有查询数据库操作,则由 php 连接数据库(用户 密码 ip)发起查询的操作
+
+## 14.3 部署安装
+
+
+```shell
+# 安装 nginx:如果编译安装可以跳过
+[root@localhost ~]# yum install nginx -y
+# 安装 php 全家桶
+[root@localhost ~]# yum install php* -y
+# 更新 php-fmp listen 配置项
+[root@localhost ~]# vim /etc/php-fpm.d/www.conf
+......
+;listen = /run/php-fpm/www.sock
+listen = 9000
+......
+[root@localhost ~]# systemctl enable --now php-fpm
+# 安装 marinedb 数据库
+[root@localhost ~]# yum install -y mariadb-server mariadb
+[root@localhost ~]# systemctl enable --now mariadb
+# 设置数据库 root 用户密码
+[root@localhost ~]# mysqladmin password '123456'
+[root@localhost ~]# mysql -uroot -p123456 -e "show databases;"
++--------------------+
+| Database |
++--------------------+
+| information_schema |
+| mysql |
+| performance_schema |
++--------------------+
+# 准备测试页面
+[root@localhost ~]# mkdir -pv /data/nginx/lnmp
+[root@localhost ~]# cat << EOF > /data/nginx/lnmp/index.php
+
+EOF
+# 测试 index.php 运行正确
+[root@localhost ~]# php /data/nginx/lnmp/index.php
+# 添加 nginx vhost 配置文件:将 php 请求转给 php-fpm 处理
+[root@localhost ~]# cat << EOF > /etc/nginx/conf.d/php.conf
+server {
+ listen 80;
+ server_name php.iproot.cn;
+ root /data/nginx/lnmp;
+
+ location / {
+ index index.php index.html;
+ }
+ location ~ \.php$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
+}
+EOF
+[root@localhost ~]# nginx -s reload
+# 测试验证
+[root@localhost ~]# curl -I -H 'Hostname: php.iproute.cn' 172.16.175.129
+HTTP/1.1 200 OK
+Server: nginx/1.20.1
+
+```
+
+## 14.4 相关配置
+
+**设置 fastcgi 服务器地址**
+
+```shell
+Syntax: fastcgi_pass address;
+Default:-
+Context:location,if in location
+# 语法示例:可以指定为域名或IP地址以及端口
+fastcgi_pass location:9000;
+fastcgi_pass unix:/tmp/fastcgi.socket;
+```
+
+**设置 fastcgi 默认首页文件**
+
+```shell
+Syntax: fastcgi_index name;
+Default:-
+Context:http,server,location
+```
+
+**设置 fastcgi_param 传递变量**
+
+```shell
+Syntax: fastcgi_param parameter value [if_not_empty];
+Default:-
+Context:http,server,location
+#语法示例
+fastcgi_index index.php;
+fastcgi_param SCRIPT_FILENAME /code$fastcgi_script_name;
+```
+
+# 15. 数据库管理应用
+
+为了方便的使用数据库,我们可以安装数据库图形化管理工具 phpmyadmin
+
+## 15.1 安装部署
+
+```shell
+# 为数据库管理工具创建虚拟主机
+[root@localhost ~]# vim /apps/nginx/conf.d/mysql.conf
+server {
+ listen 80;
+ server_name mysql.iproot.cn;
+ root /code/phpmyadmin;
+
+ location / {
+ index index.php index.html;
+ }
+
+ location ~ \.php$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
+}
+[root@localhost ~]# nginx -t
+# 下载phpmyadmin源码
+[root@localhost ~]# cd /code/
+[root@localhost code]# wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip
+# 解压软件包,并且重命名
+[root@localhost phpmyadmin]# unzip phpMyAdmin-5.1.1-all-languages.zip
+[root@localhost phpmyadmin]# mv phpMyAdmin-5.1.1-all-languages phpmyadmin
+# 添加session文件夹权限
+[root@localhost phpmyadmin]# chown nginx.nginx /var/lib/php/session
+```
+
+下面浏览器访问 phpmyadmin 页面,同样记得更改 windows下的 hosts 文件
+
+
+
+输入数据库用户名 `root` 和密码 `123456` 就可以进入图形化数据库管理页面了
+
+
+
+
+# 16. 博客系统
+
+## 16.1 部署虚拟主机
+
+```bash
+# 为博客创建虚拟主机
+[root@localhost ~]# vim /apps/nginx/conf.d/typecho.conf
+server {
+ listen 80;
+ server_name blog.iproot.cn;
+ root /code/typecho;
+ index index.php index.html;
+
+ location ~ .*\.php(\/.*)*$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
+}
+
+# 检查nginx配置文件,并且重启
+[root@localhost ~]# nginx -t
+[root@localhost ~]# systemctl restart nginx
+
+# 创建typecho目录
+[root@localhost ~]# mkdir /code/typecho
+[root@localhost ~]# cd /code/typecho
+
+[root@localhost ~]# wget https://github.com/typecho/typecho/releases/latest/download/typecho.zip
+
+# 解压源码
+[root@localhost ~]# unzip typecho.zip
+```
+
+## 16.2 创建数据库
+
+点击数据库,输入数据库名之后,就可以点击创建
+
+
+
+## 16.3 安装博客系统
+
+下面就可以开始进入网站安装的部分了,访问博客系统页面
+
+
+
+赋予网站根目录下usr/uploads目录权限
+
+```shell
+[root@localhost typecho]# chmod a+w usr/uploads/
+```
+
+继续下一步,填写数据库密码和网站后台管理员密码
+
+
+
+点击开始安装之后,会出现了如下页面,这个是因为php的用户是nginx用户,而/code/typecho文件夹是root用户的,所以这个网站根本没有权限保存数据相关的配置到文件夹中
+
+
+
+方法一:直接将typecho文件夹赋予nginx权限
+
+方法二:手动去帮助网站创建网站没有权限的配置文件,下面将会演示方法二
+
+直接在/code/typecho下创建`config.inc.php`文件,然后将网页提示内容写入这个文件中
+
+```shell
+[root@localhost typecho]# vim /code/typecho/config.inc.php
+复制网页上的内容进去
+```
+
+配置文件创建完成之后,可以点击`创建完毕,继续安装>>`
+
+下面是安装成功的页面
+
+
+
+
+
+## 16.4 切换主题
+
+默认的主题如下,界面比较的简洁,我们可以给这个网站替换主题,也可以借此加深熟悉我们对Linux命令行的熟练程度
+
+
+
+第三方主题商店:https://www.typechx.com/
+
+我们尝试更换这个主题
+
+
+
+选择模板下载
+
+
+
+然后在打开的github仓库中下载ZIP压缩包
+
+
+
+将下载好的主题压缩包上传到博客主题的目录`/code/typecho/usr/themes`
+
+
+
+然后解压主题包,并且将名称改为简单一点的
+
+```bash
+[root@localhost themes]# unzip Typecho-Butterfly-main.zip
+[root@localhost themes]# ls
+Typecho-Butterfly-main Typecho-Butterfly-main.zip default
+[root@localhost themes]# mv Typecho-Butterfly-main butterfly
+[root@localhost themes]# rm -rf Typecho-Butterfly-main.zip
+```
+
+然后登录到博客后台,在设置里更换主题
+
+
+
+然后回到博客首页刷新一下,就可以看到新的主题已经应用了~
+
+
+
+会有一些图片资源的丢失,稍微了解一点前端知识,就可以将其完善好了。不懂前端的同学,可以去找一些简单一点的主题。
+
+
+
+# 17. 网盘服务
+
+## 17.1 部署虚拟主机
+
+```bash
+# 为网盘创建虚拟主机
+[root@localhost themes]# vim /apps/nginx/conf.d/kod.conf
+server {
+ listen 80;
+ server_name kod.iproot.cn;
+ root /code/kod;
+ index index.php index.html;
+
+ location ~ .*\.php(\/.*)*$ {
+ root /code/kod;
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
+}
+
+# 检查nginx配置文件,并且重启
+[root@localhost ~]# nginx -t
+[root@localhost ~]# systemctl restart nginx
+
+# 下载源代码然后解压重命名
+[root@localhost ~]# mkdir /code/kod
+[root@localhost ~]# cd /code/kod
+[root@localhost kod]# wget https://static.kodcloud.com/update/download/kodbox.1.23.zip
+
+# 解压源码
+[root@localhost kod]# unzip kodbox.1.23.zip
+```
+
+## 17.2 创建数据库
+
+
+
+## 17.3 安装网盘系统
+
+浏览器访问此站点,我们发现目录权限,这个比较重要
+
+
+
+```bash
+# 设置权限
+[root@localhost kod]# chown -R nginx.nginx /code/kod
+```
+
+添加完成之后,刷新页面,可以看到所有条件都已经符合,就可以直接点击下一步了
+
+
+
+填写数据库密码和数据库名
+
+
+
+设置系统密码
+
+
+
+完成网站安装
+
+
+
+
+
+下面根据自己的喜好,进行简单的设置就可以正常使用啦!
+
+
+
+我们也可以直接在这个上面编辑Linux上的文件,比如我们之前创建的php文件
+
+
+
+# 18. 友情提示
+
+如何各位同学不是搭建在自己虚拟机上的,是去租用阿里云或者腾讯云,直接搭建,并且购买域名,就可以让自己的网站在互联网上永远在线
\ No newline at end of file
diff --git a/02.企业服务/05.Nginx/HTTP请求包处理流程.png b/02.企业服务/05.Nginx/HTTP请求包处理流程.png
new file mode 100644
index 0000000..fc763d8
Binary files /dev/null and b/02.企业服务/05.Nginx/HTTP请求包处理流程.png differ
diff --git a/02.企业服务/05.Nginx/LNMP工作流程01.png b/02.企业服务/05.Nginx/LNMP工作流程01.png
new file mode 100644
index 0000000..8b20541
Binary files /dev/null and b/02.企业服务/05.Nginx/LNMP工作流程01.png differ
diff --git a/02.企业服务/05.Nginx/LNMP工作流程02.png b/02.企业服务/05.Nginx/LNMP工作流程02.png
new file mode 100644
index 0000000..f51590e
Binary files /dev/null and b/02.企业服务/05.Nginx/LNMP工作流程02.png differ
diff --git a/02.企业服务/05.Nginx/Nginx架构.png b/02.企业服务/05.Nginx/Nginx架构.png
new file mode 100644
index 0000000..6c203a4
Binary files /dev/null and b/02.企业服务/05.Nginx/Nginx架构.png differ
diff --git a/02.企业服务/05.Nginx/Nginx进程模型.png b/02.企业服务/05.Nginx/Nginx进程模型.png
new file mode 100644
index 0000000..eaa8139
Binary files /dev/null and b/02.企业服务/05.Nginx/Nginx进程模型.png differ
diff --git a/02.企业服务/05.Nginx/Nginx进程模型工作细节01.png b/02.企业服务/05.Nginx/Nginx进程模型工作细节01.png
new file mode 100644
index 0000000..b6f3c09
Binary files /dev/null and b/02.企业服务/05.Nginx/Nginx进程模型工作细节01.png differ
diff --git a/02.企业服务/05.Nginx/Nginx进程间通信.png b/02.企业服务/05.Nginx/Nginx进程间通信.png
new file mode 100644
index 0000000..caff134
Binary files /dev/null and b/02.企业服务/05.Nginx/Nginx进程间通信.png differ
diff --git a/02.企业服务/05.Nginx/https测试验证.png b/02.企业服务/05.Nginx/https测试验证.png
new file mode 100644
index 0000000..a3d0e2c
Binary files /dev/null and b/02.企业服务/05.Nginx/https测试验证.png differ
diff --git a/02.企业服务/05.Nginx/image-20211106114747284-1763003737062-61.png b/02.企业服务/05.Nginx/image-20211106114747284-1763003737062-61.png
new file mode 100644
index 0000000..5846400
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20211106114747284-1763003737062-61.png differ
diff --git a/02.企业服务/05.Nginx/image-20211106114944358-1763003744379-64.png b/02.企业服务/05.Nginx/image-20211106114944358-1763003744379-64.png
new file mode 100644
index 0000000..5695ba8
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20211106114944358-1763003744379-64.png differ
diff --git a/02.企业服务/05.Nginx/image-20240715215937058-1763003817741-67.png b/02.企业服务/05.Nginx/image-20240715215937058-1763003817741-67.png
new file mode 100644
index 0000000..49dfd03
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20240715215937058-1763003817741-67.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221202018.png b/02.企业服务/05.Nginx/image-20250118221202018.png
new file mode 100644
index 0000000..9c04f14
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221202018.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221344667.png b/02.企业服务/05.Nginx/image-20250118221344667.png
new file mode 100644
index 0000000..cd68b8d
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221344667.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221414487.png b/02.企业服务/05.Nginx/image-20250118221414487.png
new file mode 100644
index 0000000..39da26f
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221414487.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221502963.png b/02.企业服务/05.Nginx/image-20250118221502963.png
new file mode 100644
index 0000000..4b009f7
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221502963.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221634385.png b/02.企业服务/05.Nginx/image-20250118221634385.png
new file mode 100644
index 0000000..4da4c1a
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221634385.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221843976.png b/02.企业服务/05.Nginx/image-20250118221843976.png
new file mode 100644
index 0000000..e1d1783
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221843976.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221920089.png b/02.企业服务/05.Nginx/image-20250118221920089.png
new file mode 100644
index 0000000..6d7a0e1
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221920089.png differ
diff --git a/02.企业服务/05.Nginx/image-20250118221958932.png b/02.企业服务/05.Nginx/image-20250118221958932.png
new file mode 100644
index 0000000..2ae3a7f
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250118221958932.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207200242332.png b/02.企业服务/05.Nginx/image-20250207200242332.png
new file mode 100644
index 0000000..5246ae7
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207200242332.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207200300668.png b/02.企业服务/05.Nginx/image-20250207200300668.png
new file mode 100644
index 0000000..1ba2823
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207200300668.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207200725398.png b/02.企业服务/05.Nginx/image-20250207200725398.png
new file mode 100644
index 0000000..1a2292a
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207200725398.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201018894.png b/02.企业服务/05.Nginx/image-20250207201018894.png
new file mode 100644
index 0000000..162c1d1
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201018894.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201110920.png b/02.企业服务/05.Nginx/image-20250207201110920.png
new file mode 100644
index 0000000..004c9d6
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201110920.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201132377.png b/02.企业服务/05.Nginx/image-20250207201132377.png
new file mode 100644
index 0000000..3df894c
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201132377.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201248174.png b/02.企业服务/05.Nginx/image-20250207201248174.png
new file mode 100644
index 0000000..18dd206
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201248174.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201334236.png b/02.企业服务/05.Nginx/image-20250207201334236.png
new file mode 100644
index 0000000..68a0f75
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201334236.png differ
diff --git a/02.企业服务/05.Nginx/image-20250207201405074.png b/02.企业服务/05.Nginx/image-20250207201405074.png
new file mode 100644
index 0000000..c49d877
Binary files /dev/null and b/02.企业服务/05.Nginx/image-20250207201405074.png differ
diff --git a/02.企业服务/05.Nginx/phpmyadmin登录页面.png b/02.企业服务/05.Nginx/phpmyadmin登录页面.png
new file mode 100644
index 0000000..5a4eaf4
Binary files /dev/null and b/02.企业服务/05.Nginx/phpmyadmin登录页面.png differ
diff --git a/02.企业服务/05.Nginx/phpmyadmin管理页面.png b/02.企业服务/05.Nginx/phpmyadmin管理页面.png
new file mode 100644
index 0000000..c4ffb34
Binary files /dev/null and b/02.企业服务/05.Nginx/phpmyadmin管理页面.png differ
diff --git a/02.企业服务/05.Nginx/创建typecho数据库.png b/02.企业服务/05.Nginx/创建typecho数据库.png
new file mode 100644
index 0000000..179c21b
Binary files /dev/null and b/02.企业服务/05.Nginx/创建typecho数据库.png differ
diff --git a/02.企业服务/05.Nginx/初始化配置.png b/02.企业服务/05.Nginx/初始化配置.png
new file mode 100644
index 0000000..ae3ab79
Binary files /dev/null and b/02.企业服务/05.Nginx/初始化配置.png differ
diff --git a/02.企业服务/05.Nginx/安装博客系统.png b/02.企业服务/05.Nginx/安装博客系统.png
new file mode 100644
index 0000000..34c0916
Binary files /dev/null and b/02.企业服务/05.Nginx/安装博客系统.png differ
diff --git a/02.企业服务/05.Nginx/状态页.png b/02.企业服务/05.Nginx/状态页.png
new file mode 100644
index 0000000..cce2a92
Binary files /dev/null and b/02.企业服务/05.Nginx/状态页.png differ
diff --git a/02.企业服务/05.Nginx/设置网站后台管理员密码.png b/02.企业服务/05.Nginx/设置网站后台管理员密码.png
new file mode 100644
index 0000000..2cf1e7b
Binary files /dev/null and b/02.企业服务/05.Nginx/设置网站后台管理员密码.png differ
diff --git a/02.企业服务/06.反向代理.md b/02.企业服务/06.反向代理.md
new file mode 100644
index 0000000..915dc08
--- /dev/null
+++ b/02.企业服务/06.反向代理.md
@@ -0,0 +1,242 @@
+# 1. Nginx代理服务
+
+- 代理一词往往并不陌生, 该服务我们常常用到如(代理理财、代理租房、代理收货等等)
+
+
+
+- 在没有代理模式的情况下,客户端和Nginx服务端,都是客户端直接请求服务端,服务端直接响应客户端。
+
+
+
+- 那么在互联网请求里面,客户端往往无法直接向服务端发起请求,那么就需要用到代理服务,来实现客户端和服务通信
+
+
+
+# 2. Nginx代理服务常见模式
+
+- Nginx作为代理服务,按照应用场景模式进行总结,代理分为正向代理、反向代理
+
+
+
+- 正向代理与反向代理的区别
+
+ - 区别在于形式上服务的”对象”不一样
+ - 正向代理代理的对象是客户端,为客户端服务
+ - 反向代理代理的对象是服务端,为服务端服务
+
+# 3. Nginx代理服务支持协议
+
+- Nginx作为代理服务,可支持的代理协议非常的多
+
+
+
+- 如果将Nginx作为反向代理服务,常常会用到如下几种代理协议
+
+
+
+# 4. Nginx反向代理配置语法
+
+- 代理配置语法
+
+```bash
+Syntax: proxy_pass URL;
+Default: —
+Context: location, if in location, limit_except
+
+http://localhost:8000/uri/
+http://192.168.56.11:8000/uri/
+http://unix:/tmp/backend.socket:/uri/
+```
+
+- url跳转修改返回Location[不常用]
+
+```bash
+Syntax: proxy_redirect default;
+proxy_redirect off;proxy_redirect redirect replacement;
+Default: proxy_redirect default;
+Context: http, server, location
+```
+
+- 添加发往后端服务器的请求头信息
+
+```bash
+Syntax: proxy_set_header field value;
+Default: proxy_set_header Host $proxy_host;
+ proxy_set_header Connection close;
+Context: http, server, location
+
+# 用户请求的时候HOST的值是www.test.com, 那么代理服务会像后端传递请求的还是www.test.com
+proxy_set_header Host $http_host;
+# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
+proxy_set_header X-Real-IP $remote_addr;
+# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+```
+
+- 代理到后端的TCP连接、响应、返回等超时时间
+
+```bash
+//nginx代理与后端服务器连接超时时间(代理连接超时)
+Syntax: proxy_connect_timeout time;
+Default: proxy_connect_timeout 60s;
+Context: http, server, location
+
+//nginx代理等待后端服务器的响应时间
+Syntax: proxy_read_timeout time;
+Default: proxy_read_timeout 60s;
+Context: http, server, location
+
+//后端服务器数据回传给nginx代理超时时间
+Syntax: proxy_send_timeout time;
+Default: proxy_send_timeout 60s;
+Context: http, server, location
+```
+
+- proxy_buffer代理缓冲区
+
+```bash
+//nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
+Syntax: proxy_buffering on | off;
+Default: proxy_buffering on;
+Context: http, server, location
+
+//设置nginx代理保存用户头信息的缓冲区大小
+Syntax: proxy_buffer_size size;
+Default: proxy_buffer_size 4k|8k;
+Context: http, server, location
+
+//proxy_buffers 缓冲区
+Syntax: proxy_buffers number size;
+Default: proxy_buffers 8 4k|8k;
+Context: http, server, location
+```
+
+- 常用优化配置
+ - Proxy代理网站常用优化配置如下,将配置写入新文件,调用时使用include引用即可
+
+```bash
+[root@Nginx ~]# vim /etc/nginx/proxy_params
+proxy_set_header Host $http_host;
+proxy_set_header X-Real-IP $remote_addr;
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+proxy_connect_timeout 30;
+proxy_send_timeout 60;
+proxy_read_timeout 60;
+
+proxy_buffering on;
+proxy_buffer_size 32k;
+proxy_buffers 4 128k;
+```
+
+- 重复使用配置
+ - 代理配置location时调用方便后续多个Location重复使用
+
+```bash
+location / {
+ proxy_pass http://127.0.0.1:8080;
+ include proxy_params;
+}
+```
+
+# 5. Nginx反向代理场景实践
+
+- Nginx反向代理配置实例
+
+
+
+- web01服务器,配置一个网站,监听在8080
+
+```bash
+[root@web01 ~]# cd /etc/nginx/conf.d/
+[root@web01 conf.d]# vim web.conf
+server {
+ listen 8080;
+ server_name localhost;
+
+ location / {
+ root /code/8080;
+ index index.html;
+ allow all;
+ }
+}
+[root@web01 conf.d]# nginx -t
+nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
+nginx: configuration file /etc/nginx/nginx.conf test is successful
+[root@web01 conf.d]# systemctl restart nginx
+[root@web01 ~]# mkdir -p /code/8080
+[root@web01 ~]# echo "listening 8080 ..." > /code/8080/index.html
+```
+
+- proxy代理服务,配置监听80端口,使能够通过代理服务器访问到后端的192.168.175.20的8080端口站点内容
+
+```bash
+[root@proxy ~]# cd /etc/nginx/conf.d/
+[root@proxy conf.d]# vim proxy_web_node1.conf
+server {
+ listen 80;
+ server_name proxy.test.com;
+
+ location / {
+ proxy_pass http://192.168.175.20:8080;
+ }
+}
+[root@proxy conf.d]# nginx -t
+[root@proxy conf.d]# systemctl restart nginx
+```
+
+- 存在的问题,通过抓包可以看到客户端是使用域名对网站进行访问的,但是代理却是使用的IP地址加端口号
+- 当访问80端口的时候,没有域名的情况下,默认会去找排在最上面的那个配置文件。
+- 所以我们需要解决这个问题,保留住最开始的请求头部信息。
+
+
+
+
+
+- 修改配置文件,使用`proxy_set_header`模块
+
+```bash
+[root@proxy conf.d]# vim proxy_web_node1.conf
+server {
+ listen 80;
+ server_name proxy.test.com;
+
+ location / {
+ proxy_pass http://192.168.175.20:8080;
+ proxy_set_header Host $http_host;
+ }
+}
+```
+
+- 使用http1.1协议
+
+```bash
+server {
+ listen 80;
+ server_name proxy.test.com;
+
+ location / {
+ proxy_pass http://192.168.175.20:8080;
+ proxy_set_header Host $http_host;
+ proxy_http_version 1.1;
+ }
+}
+```
+
+- 在生产环境中,我们必须要记录客户端的来源IP,如果所有的访问日志,全都来源于代理,那么我们根本不知道都有哪些地区的用户访问了我们什么页面。
+ - 还需要使用`proxy_set_header`
+
+```bash
+server {
+ listen 80;
+ server_name proxy.test.com;
+
+ location / {
+ proxy_pass http://192.168.175.20:8080;
+ proxy_set_header Host $http_host;
+ proxy_http_version 1.1;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+}
+```
+
diff --git a/02.企业服务/06.反向代理/image-20210711132943764.png b/02.企业服务/06.反向代理/image-20210711132943764.png
new file mode 100644
index 0000000..3fd22d4
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711132943764.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711133242593.png b/02.企业服务/06.反向代理/image-20210711133242593.png
new file mode 100644
index 0000000..6bc3209
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711133242593.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711141653692-1626395774911-1739587022188226.png b/02.企业服务/06.反向代理/image-20210711141653692-1626395774911-1739587022188226.png
new file mode 100644
index 0000000..6d63a52
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711141653692-1626395774911-1739587022188226.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711142214493.png b/02.企业服务/06.反向代理/image-20210711142214493.png
new file mode 100644
index 0000000..3816d7e
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711142214493.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711143359615.png b/02.企业服务/06.反向代理/image-20210711143359615.png
new file mode 100644
index 0000000..1f9ff8e
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711143359615.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711143720275.png b/02.企业服务/06.反向代理/image-20210711143720275.png
new file mode 100644
index 0000000..43fffd9
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711143720275.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711151756044.png b/02.企业服务/06.反向代理/image-20210711151756044.png
new file mode 100644
index 0000000..ccb8114
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711151756044.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711154444696.png b/02.企业服务/06.反向代理/image-20210711154444696.png
new file mode 100644
index 0000000..6840d7c
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711154444696.png differ
diff --git a/02.企业服务/06.反向代理/image-20210711154508713.png b/02.企业服务/06.反向代理/image-20210711154508713.png
new file mode 100644
index 0000000..1f90981
Binary files /dev/null and b/02.企业服务/06.反向代理/image-20210711154508713.png differ
diff --git a/02.企业服务/07.负载均衡.md b/02.企业服务/07.负载均衡.md
new file mode 100644
index 0000000..dfa6d50
--- /dev/null
+++ b/02.企业服务/07.负载均衡.md
@@ -0,0 +1,2869 @@
+# 1. Nginx负载均衡基本概述
+
+## 1.1 为什么要使用负载均衡
+
+- 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台Web服务器组成集群,前端使用Nginx负载均衡,将请求分散的打到我们的后端服务器集群中,实现负载的分发。那么会大大提升系统的吞吐率、请求性能、高容灾
+
+
+
+- 往往我们接触的最多的是`SLB(Server Load Balance)`负载均衡,实现最多的也是`SLB`、那么`SLB`它的调度节点和服务节点通常是在一个地域里面。那么它在这个小的逻辑地域里面决定了他对部分服务的实时性、响应性是非常好的。
+- 所以说当海量用户请求过来以后,它同样是请求调度节点,调度节点将用户的请求转发给后端对应的服务节点,服务节点处理完请求后在转发给调度节点,调度节点最后响应给用户节点。这样也能实现一个均衡的作用,那么**Nginx**则是一个典型的`SLB`
+
+- 负载均衡的叫法有很多
+ - 负载均衡
+ - Load Balance
+ - LB
+- 公有云中叫法
+ - SLB 阿里云负载均衡
+ - QLB 青云负载均衡
+ - CLB 腾讯云负载均衡
+ - ULB ucloud负载均衡
+- 常见的负载均衡的软件
+ - Nginx
+ - Haproxy
+ - LVS
+
+## 1.2 四层负载均衡
+
+ 所谓四层负载均衡指的是`OSI`七层模型中的传输层,那么传输层**Nginx**已经能支持**TCP/IP**的控制,所以只需要对客户端的请求进行**TCP/IP**协议的包转发就可以实现负载均衡,那么它的好处是性能非常快、只需要底层进行应用处理,而不需要进行一些复杂的逻辑。
+
+
+
+## 1.3 七层负载均衡
+
+ 七层负载均衡它是在应用层,那么它可以完成很多应用方面的协议请求,比如我们说的**http**应用的负载均衡,它可以实现**http**信息的改写、头信息的改写、安全应用规则控制、**URL**匹配规则控制、以及转发、**rewrite**等等的规则,所以在应用层的服务里面,我们可以做的内容就更多,那么**Nginx**则是一个典型的七层负载均衡`SLB`
+
+
+
+## 1.4 四层负载均衡与七层负载均衡区别
+
+ 四层负载均衡数据包在底层就进行了分发,而七层负载均衡数据包则是在最顶层进行分发、由此可以看出,七层负载均衡效率没有四负载均衡高。
+
+ 但七层负载均衡更贴近于服务,如:**http**协议就是七层协议,我们可以用**Nginx**可以作会话保持,**URL**路径规则匹配、**head**头改写等等,这些是四层负载均衡无法实现的。
+
+ **注意:四层负载均衡不识别域名,七层负载均衡识别域名**
+
+# 2. Nginx负载均衡配置场景
+
+ Nginx要实现负载均衡需要用到`proxy_pass`代理模块配置.
+
+ Nginx负载均衡与**Nginx**代理不同地方在于,**Nginx**的一个`location`仅能代理一台服务器,而**Nginx**负载均衡则是将客户端请求代理转发至一组**upstream**虚拟服务池.
+
+
+
+## 2.1 Nginx upstream虚拟配置语法
+
+```bash
+Syntax: upstream name { ... }
+Default: -
+Context: http
+
+#upstream例
+upstream backend {
+ server backend1.example.com weight=5;
+ server backend2.example.com:8080;
+ server unix:/tmp/backend3;
+ server backup1.example.com:8080 backup;
+}
+server {
+ location / {
+ proxy_pass http://backend;
+ }
+}
+```
+
+## 2.2 环境准备
+
+| 角色 | 地址 | 主机名 |
+| :---- | :---------------------- | :----- |
+| LB01 | ens33:**192.168.88.10** | lb01 |
+| web01 | ens33:**192.168.88.20** | web01 |
+| web02 | ens33:**192.168.88.30** | web02 |
+
+## 2.3 Web01服务器上配置nginx
+
+```bash
+[root@web01 ~]# cd /etc/nginx/conf.d/
+[root@web01 conf.d]# vim node.conf
+server {
+ listen 80;
+ server_name node.test.com;
+ location / {
+ root /code/node;
+ index index.html;
+ }
+}
+[root@web01 conf.d]# mkdir -p /code/node
+[root@web01 conf.d]# echo "web01 ..." > /code/node/index.html
+[root@web01 conf.d]# systemctl restart nginx
+# 关闭防火墙和SElinux
+[root@web02 conf.d]# setenforce 0
+[root@web02 conf.d]# systemctl stop firewalld
+```
+
+## 2.4 Web02服务器上配置nginx
+
+```bash
+[root@web02 ~]# cd /etc/nginx/conf.d/
+[root@web02 conf.d]# vim node.conf
+server {
+ listen 80;
+ server_name node.test.com;
+ location / {
+ root /code/node;
+ index index.html;
+ }
+}
+[root@web02 conf.d]# mkdir -p /code/node
+[root@web02 conf.d]# echo "web02 ..." > /code/node/index.html
+[root@web02 conf.d]# systemctl restart nginx
+# 关闭防火墙和SElinux
+[root@web02 conf.d]# setenforce 0
+[root@web02 conf.d]# systemctl stop firewalld
+```
+
+## 2.5 配置Nginx负载均衡
+
+```bash
+[root@lb01 ~]# cd /etc/nginx/conf.d/
+
+[root@lb01 conf.d]# vim /etc/nginx/proxy_params
+proxy_set_header Host $http_host;
+proxy_set_header X-Real-IP $remote_addr;
+proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
+proxy_connect_timeout 30;
+proxy_send_timeout 60;
+proxy_read_timeout 60;
+
+proxy_buffering on;
+proxy_buffer_size 32k;
+proxy_buffers 4 128k;
+
+[root@lb01 conf.d]# vim node_proxy.conf
+upstream node {
+ server 192.168.88.20:80;
+ server 192.168.88.30:80;
+}
+server {
+ listen 80;
+ server_name node.test.com;
+
+ location / {
+ proxy_pass http://node;
+ include proxy_params;
+ }
+}
+
+[root@lb01 conf.d]# nginx -t
+[root@lb01 conf.d]# systemctl restart nginx
+
+# 配置hosts解析
+[root@lb01 conf.d]# vim /etc/hosts
+192.168.88.10 node.test.com
+```
+
+windows访问,更改windows下的hosts文件
+
+- 打开浏览器访问:http://node.test.com
+
+
+
+
+
+## 2.6 负载均衡常见典型故障
+
+ 如果后台服务连接超时,Nginx是本身是有机制的,如果出现一个节点down掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、502、500,这个时候你需要加一个负载均衡的设置,如下:proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;意思是,当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率。
+
+```bash
+server {
+ listen 80;
+ server_name node.test.com;
+
+ location / {
+ proxy_pass http://node;
+ proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_404;
+ }
+}
+```
+
+# 3. Nginx负载均衡调度算法
+
+| **调度算法** | **概述** |
+| :----------- | :----------------------------------------------------------- |
+| 轮询 | 按时间顺序逐一分配到不同的后端服务器(默认) |
+| weight | 加权轮询,weight值越大,分配到的访问几率越高 |
+| ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器 |
+| url_hash | 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器 |
+| least_conn | 最少链接数,那个机器链接数少就分发 |
+
+## 3.1 Nginx负载均衡[rr]轮询具体配置
+
+```bash
+upstream load_pass {
+ server 192.168.88.10:80;
+ server 192.168.88.20:80;
+}
+```
+
+## 3.2 Nginx负载均衡[wrr]权重轮询具体配置
+
+```bash
+upstream load_pass {
+ server 192.168.88.10:80 weight=5;
+ server 192.168.88.20:80;
+}
+```
+
+## 3.3 Nginx负载均衡ip_hash
+
+- **ip_hash**: 根据客户端IP地址进行哈希,确保来自同一IP的客户端总是被转发到同一台后端服务器
+- 具体配置不能和weight一起使用。
+
+```bash
+#如果客户端都走相同代理, 会导致某一台服务器连接过多
+upstream load_pass {
+ ip_hash;
+ server 192.168.88.10:80;
+ server 192.168.88.20:80;
+}
+```
+
+# 4. Nginx负载均衡后端状态
+
+- 后端Web服务器在前端Nginx负载均衡调度中的状态
+
+| **状态** | **概述** |
+| :----------- | :-------------------------------- |
+| down | 当前的server暂时不参与负载均衡 |
+| backup | 预留的备份服务器 |
+| max_fails | 允许请求失败的次数 |
+| fail_timeout | 经过max_fails失败后, 服务暂停时间 |
+| max_conns | 限制最大的接收连接数 |
+
+## 4.1 测试down状态测试该Server不参与负载均衡的调度
+
+```bash
+upstream load_pass {
+ #不参与任何调度, 一般用于停机维护
+ server 192.168.88.10:80 down;
+}
+```
+
+## 4.2 backup以及down状态
+
+```bash
+upstream load_pass {
+ server 192.168.88.10:80 backup;
+ server 192.168.88.20:80 max_fails=1 fail_timeout=10s;
+}
+
+location / {
+ proxy_pass http://load_pass;
+ include proxy_params;
+}
+```
+
+## 4.3 max_fails失败次数和fail_timeout多少时间内失败多少次则标记down
+
+```bash
+upstream load_pass {
+ server 192.168.88.10:80;
+ server 192.168.88.20:80 max_fails=2 fail_timeout=10s;
+}
+```
+
+## 4.4 max_conns最大TCP连接数
+
+```bash
+upstream load_pass {
+ server 192.168.88.10:80;
+ server 192.168.88.20:80 max_conns=1;
+}
+```
+
+# 5. Nginx负载均衡健康检查
+
+- 在Nginx官方模块提供的模块中,没有对负载均衡后端节点的健康检查模块,但可以使用第三方模块。
+ `nginx_upstream_check_module`来检测后端服务的健康状态。
+- 第三方模块项目地址:https://github.com/yaoweibin/nginx_upstream_check_module
+
+- 安装依赖包
+
+```bash
+[root@lb01 ~]# yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel patch
+```
+
+- 下载nginx源码包以及nginx_upstream_check模块第三方模块
+
+```bash
+[root@lb01 ~]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
+[root@lb01 ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
+```
+
+- 解压nginx源码包以及第三方模块
+
+```bash
+[root@lb01 ~]# tar xf nginx-1.20.1.tar.gz
+[root@lb01 ~]# unzip master.zip
+```
+
+- 进入nginx目录,打补丁(nginx的版本是1.14补丁就选择1.14的,p1代表在nginx目录,p0是不在nginx目录)
+
+```bash
+[root@lb01 ~]# cd nginx-1.20.1
+[root@lb01 nginx-1.14.2]# patch -p1 <../nginx_upstream_check_module-master/check_1.20.1+.patch
+[root@lb01 nginx-1.14.2]# ./configure --prefix=/etc/nginx \
+--sbin-path=/usr/sbin/nginx \
+--modules-path=/usr/lib64/nginx/modules \
+--conf-path=/etc/nginx/nginx.conf \
+--error-log-path=/var/log/nginx/error.log \
+--http-log-path=/var/log/nginx/access.log \
+--pid-path=/var/run/nginx.pid \
+--lock-path=/var/run/nginx.lock \
+--http-client-body-temp-path=/var/cache/nginx/client_temp \
+--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
+--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
+--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
+--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
+--user=nginx --group=nginx --with-compat \
+--with-file-aio --with-threads --with-http_addition_module \
+--with-http_auth_request_module --with-http_dav_module \
+--with-http_flv_module --with-http_gunzip_module \
+--with-http_gzip_static_module --with-http_mp4_module \
+--with-http_random_index_module --with-http_realip_module \
+--with-http_secure_link_module --with-http_slice_module \
+--with-http_ssl_module --with-http_stub_status_module \
+--with-http_sub_module --with-http_v2_module --with-mail \
+--with-mail_ssl_module --with-stream --with-stream_realip_module \
+--with-stream_ssl_module --with-stream_ssl_preread_module \
+--add-module=/root/nginx_upstream_check_module-master \
+--with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' \
+--with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
+[root@lb01 nginx-1.14.2]# make -j 2 && make install
+[root@lb01 nginx-1.14.2]# nginx -v
+nginx version: nginx/1.14.2
+[root@lb01 nginx-1.14.2]# mkdir -p /var/cache/nginx/client_temp
+```
+
+- 在已有的负载均衡上增加健康检查的功能
+
+```bash
+[root@lb01 conf.d]# vim node_proxy.conf
+upstream node {
+ server 192.168.88.10:80 max_fails=2 fail_timeout=10s;
+ server 192.168.88.20:80 max_fails=2 fail_timeout=10s;
+ check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
+ #interval 检测间隔时间,单位为毫秒
+ #rise 表示请求2次正常,标记此后端的状态为up
+ #fall 表示请求3次失败,标记此后端的状态为down
+ #type 类型为tcp
+ #timeout 超时时间,单位为毫秒
+}
+
+server {
+ listen 80;
+ server_name node.test.com;
+ location / {
+ proxy_pass http://node;
+ include proxy_params;
+ }
+
+ location /upstream_check {
+ check_status;
+ }
+}
+```
+
+# 6. Nginx负载均衡会话保持
+
+- 在使用负载均衡的时候会遇到会话保持的问题,可通过如下方式进行解决。
+ - 使用nginx的ip_hash,根据客户端的IP,将请求分配到对应的IP上
+ - 基于服务端的session会话共享(NFS,MySQL,memcache,redis,file)
+- 在解决负载均衡会话问题,我们需要了解session和cookie的区别。
+ - 浏览器端存的是cookie每次浏览器发请求到服务端时,报文头是会自动添加cookie信息的。
+ - 服务端会查询用户的cookie作为key去存储里找对应的value(session)
+ - 同一域名下的网站的cookie都是一样的,所以无论几台服务器,无论请求分配到哪一台服务器上同一用户的cookie是不变的。也就是说cookie对应的session也是唯一的。所以,这里只要保证多台业务服务器访问同一个共享存储服务器(NFS,MySQL,memcache,redis,file)就行了。
+
+## 6.1 会话保持配置
+
+测试网站选择我们之前搭建过的phpmyadmin,所以我们先再web01和web02上部署phpmyadmin
+
+- 配置php环境(web01和web02都要)
+
+```bash
+# 导入英格提供的php源,这个比较快
+vim /etc/yum.repos.d/eagle.repo
+[eagle]
+name=Eagle's lab
+baseurl=http://file.eagleslab.com:8889/%E8%AF%BE%E7%A8%8B%E7%9B%B8%E5%85%B3%E8%BD%AF%E4%BB%B6/%E4%BA%91%E8%AE%A1%E7%AE%97%E8%AF%BE%E7%A8%8B/Centos7%E6%BA%90/
+gpgcheck=0
+enabled=1
+
+# 安装php环境,php所需的组件比较多,我们可以一次性安装全面了
+yum -y install php71w php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb
+
+# 配置php-fpm用于与nginx的运行用户保持一致
+sed -i '/^user/c user = nginx' /etc/php-fpm.d/www.conf
+sed -i '/^group/c group = nginx' /etc/php-fpm.d/www.conf
+
+# 启动php-fpm
+systemctl start php-fpm
+```
+
+
+
+- 配置Nginx(web01和web02都要)
+
+```bash
+[root@web01 ~]# vim /etc/nginx/conf.d/php.conf
+server {
+ listen 80;
+ server_name php.test.com;
+ root /code/phpMyAdmin-4.8.4-all-languages;
+
+ location / {
+ index index.php index.html;
+ }
+
+ location ~ \.php$ {
+ fastcgi_pass 127.0.0.1:9000;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ include fastcgi_params;
+ }
+}
+[root@web01 ~]# nginx -t
+[root@web01 ~]# systemctl restart nginx
+```
+
+- 安装phpmyadmin (web01和web02都要)
+
+```bash
+[root@web01 ~]# cd /code
+[root@web01 code]# wget https://files.phpmyadmin.net/phpMyAdmin/4.8.4/phpMyAdmin-4.8.4-all-languages.zip
+[root@web01 code]# unzip phpMyAdmin-4.8.4-all-languages.zip
+```
+
+- 配置phpmyadmin连接远程的数据库,这个数据库可以用代理服务器安装后做测试(web01和web02都要)
+
+```bash
+[root@web01 code]# cd phpMyAdmin-4.8.4-all-languages/
+[root@web01 phpMyAdmin-4.8.4-all-languages]# cp config.sample.inc.php config.inc.php
+[root@web01 phpMyAdmin-4.8.4-all-languages]# vim config.inc.php
+$cfg['Servers'][$i]['host'] = '192.168.88.10';
+```
+
+- 配置权限(web01和web02都要)
+
+```bash
+[root@web01 ~]# chown -R nginx.nginx /var/lib/php/
+```
+
+- 在lb01上部署mariadb数据库,提供phpmyadmin访问
+
+```bash
+# 安装mariadb数据库软件
+yum install mariadb-server mariadb -y
+
+# 启动数据库并且设置开机自启动
+systemctl start mariadb
+systemctl enable mariadb
+
+# 设置mariadb的密码
+mysqladmin password '123456'
+
+# 验证数据库是否工作正常
+mysql -uroot -p123456 -e "show databases;"
++--------------------+
+| Database |
++--------------------+
+| information_schema |
+| mysql |
+| performance_schema |
+| test |
++--------------------+
+
+# 创建访问用户
+grant all privileges on *.* to root@'192.168.88.%' identified by '123456' with grant option;
+flush privileges;
+```
+
+## 6.2 使用浏览器访问页面,获取cookie信息
+
+
+
+
+
+- 查看服务器上的session
+
+```bash
+[root@web01 ~]# ll /var/lib/php/session/
+总用量 4
+-rw------- 1 www www 2625 7月 11 20:08 sess_aa3bdfab93197f49bbfddb15cb41a595
+```
+
+- 将web01上配置好的phpmyadmin以及nginx的配置文件推送到web02主机上
+
+```bash
+[root@web01 code]# scp -rp phpMyAdmin-4.8.4-all-languages root@192.168.88.30:/code/
+[root@web01 code]# scp /etc/nginx/conf.d/php.conf root@192.168.88.30:/etc/nginx/conf.d/
+```
+
+- 在web02上重启Nginx服务
+
+```bash
+[root@web02 ~]# systemctl restart nginx
+```
+
+- 在web02上配置权限
+
+```bash
+[root@web02 ~]# chown -R nginx. /var/lib/php/
+```
+
+- 接入负载均衡
+
+```bash
+[root@lb01 ~]# vim /etc/nginx/conf.d/proxy_php.com.conf
+upstream php {
+ server 192.168.88.20:80;
+ server 192.168.88.30:80;
+}
+server {
+ listen 80;
+ server_name php.test.com;
+ location / {
+ proxy_pass http://php;
+ include proxy_params;
+ }
+}
+
+[root@lb01 ~]# nginx -t
+[root@lb01 ~]# systemctl restart nginx
+```
+
+- 使用负载均衡的轮询功能之后,会发现,如果将session保存在本地文件的话,永远都登录不上去。
+
+
+
+## 6.3 使用redis解决会话登录问题
+
+- 安装redis内存数据库
+
+```bash
+[root@lb01 ~]# yum -y install redis
+```
+
+- 配置redis监听在0.0.0.0网段上
+
+```bash
+[root@lb01 ~]# sed -i '/^bind/c bind 127.0.0.1 0.0.0.0' /etc/redis.conf
+```
+
+- 启动redis
+
+```bash
+[root@lb01 ~]# systemctl start redis
+[root@lb01 ~]# systemctl enable redis
+```
+
+- php配置session连接redis
+
+```bash
+[root@web01 ~]# vim /etc/php.ini
+session.save_handler = redis
+session.save_path = "tcp://192.168.88.10:6379"
+;session.save_path = "tcp://192.168.88.10:6379?auth=centos" #如果redis存在密码,则使用该方式
+session.auto_start = 1
+
+[root@web01 ~]# vim /etc/php-fpm.d/www.conf
+#注释php-fpm.d/www.conf里面的两条内容,否则session内容会一直写入/var/lib/php/session目录中
+;php_value[session.save_handler] = files
+;php_value[session.save_path] = /var/lib/php/session
+```
+
+- 重启php-fpm
+
+```bash
+[root@web01 ~]# systemctl restart php-fpm
+```
+
+- 将web01上配置好的文件推送到web02
+
+```bash
+[root@web01 ~]# scp /etc/php.ini root@192.168.88.30:/etc/php.ini
+[root@web01 ~]# scp /etc/php-fpm.d/www.conf root@192.168.88.30:/etc/php-fpm.d/www.conf
+```
+
+- 在web02上重启php-fpm
+
+```bash
+[root@web02 ~]# systemctl restart php-fpm
+```
+
+- redis查看数据
+
+```bash
+[root@lb01 ~]# redis-cli
+127.0.0.1:6379> keys *
+1) "PHPREDIS_SESSION:7e772fe37b1488069e3c54e419df7eda"
+```
+
+
+
+# 7. Nginx四层负载均衡概述
+
+ 四层负载均衡是基于传输层协议包来封装的(如:TCP/IP),那我们前面使用到的七层是指的应用层,他的组装在四层的基础之上,无论四层还是七层都是指的OSI网络模型。
+
+ 四层+七层来做负载均衡,四层可以保证七层的负载均衡的高可用性;如:nginx就无法保证自己的服务高可用,需要依赖LVS或者keepalive。
+
+ 如:tcp协议的负载均衡,有些请求是TCP协议的(mysql、ssh),或者说这些请求只需要使用四层进行端口的转发就可以了,所以使用四层负载均衡。
+
+## 7.1 四层+七层构建大规模集群架构使用场
+
+
+
+## 7.2 四层负载均衡总结
+
+- 四层负载均衡仅能转发TCP/IP协议、UDP协议、通常用来转发端口,如:tcp/22、udp/53;
+- 四层负载均衡可以用来解决七层负载均衡端口限制问题;(七层负载均衡最大使用65535个端口号)
+- 四层负载均衡可以解决七层负载均衡高可用问题;(多台后端七层负载均衡能同事的使用)
+- 四层的转发效率比七层的高得多,但仅支持tcp/ip协议,不支持http和https协议;
+- 通常大并发场景通常会选择使用在七层负载前面增加四层负载均衡。
+
+## 7.3 Nginx四层负载均衡场景实践
+
+Nginx如何配置四层负载均衡
+
+1、通过访问负载均衡的5555端口,实际是后端的web01的22端口在提供服务;
+
+2、通过访问负载均衡的6666端口,实际是后端的mysql的3306端口在提供服务。
+
+- 创建存放四层负载均衡配置文件的目录
+
+```bash
+[root@lb01 ~]# yum install nginx-mod-stream
+[root@lb01 ~]# vim /etc/nginx/nginx.conf
+include /etc/nginx/conf.c/*.conf;
+#include /etc/nginx/conf.d/*.conf;
+[root@lb01 ~]# mkdir /etc/nginx/conf.c
+```
+
+- 配置四层负载均衡
+
+```bash
+[root@lb01 ~]# vim /etc/nginx/conf.c/lb_domain.conf
+stream {
+ upstream lb {
+ server 192.168.88.20:80 weight=5 max_fails=3 fail_timeout=30s;
+ server 192.168.88.30:80 weight=5 max_fails=3 fail_timeout=30s;
+ }
+
+ server {
+ listen 80;
+ proxy_connect_timeout 3s;
+ proxy_timeout 3s;
+ proxy_pass lb;
+ }
+}
+```
+
+- 四层负载均衡开启日志
+ - 四层负载均衡是没有access的日志的,因为在nginx.conf的配置中,access的日志格式是配置在http下的,而四层负载均衡配置实在http以外的
+ - 如果需要日志则需要配置在stream下面
+
+```bash
+[root@lb01 ~]# cd /etc/nginx/conf.c/
+[root@lb01 conf.c]# vim lb_domain.conf
+stream {
+ log_format proxy '$remote_addr $remote_port - [$time_local] $status $protocol '
+ '"$upstream_addr" "$upstream_bytes_sent" "$upstream_connect_time"' ;
+ access_log /var/log/nginx/proxy.log proxy;
+ upstream lb {
+ server 192.168.88.20:80 weight=5 max_fails=3 fail_timeout=30s;
+ server 192.168.88.30:80 weight=5 max_fails=3 fail_timeout=30s;
+ }
+
+ server {
+ listen 80;
+ proxy_connect_timeout 3s;
+ proxy_timeout 3s;
+ proxy_pass lb;
+ }
+}
+
+[root@lb01 conf.c]# nginx -t
+[root@lb01 conf.c]# systemctl restart nginx
+```
+
+- 浏览器访问域名或者IP,查看日志
+
+```bash
+[root@lb01 conf.c]# tail -f /var/log/nginx/proxy.log
+192.168.88.1 55295 - [11/Jul/2021:23:27:09 +0800] 200 TCP "192.168.88.20:80" "0" "0.001"
+192.168.88.1 64066 - [11/Jul/2021:23:27:13 +0800] 200 TCP "192.168.88.30:80" "0" "0.000"
+192.168.88.1 58528 - [11/Jul/2021:23:27:16 +0800] 200 TCP "192.168.88.20:80" "0" "0.001"
+192.168.88.1 65099 - [11/Jul/2021:23:27:20 +0800] 200 TCP "192.168.88.30:80" "0" "0.000"
+192.168.88.1 55919 - [11/Jul/2021:23:27:20 +0800] 200 TCP "192.168.88.20:80" "6460" "0.001"
+```
+
+## 7.4 Nginx四层负载均衡端口转发
+
+- 使用nginx四层负载均衡实现tcp的转发
+
+```bash
+请求负载均衡 5555 ---> 192.168.88.20:22;
+请求负载均衡 6666 ---> 192.168.88.30:3306;
+```
+
+- 配置nginx四层负载均衡实现tcp的转发
+
+```bash
+[root@lb01 ~]# vim /etc/nginx/conf.c/lb_domain.conf
+stream {
+ log_format proxy '$remote_addr $remote_port - [$time_local] $status $protocol '
+ '"$upstream_addr" "$upstream_bytes_sent" "$upstream_connect_time"' ;
+ access_log /var/log/nginx/proxy.log proxy;
+
+#定义转发ssh的22端口
+ upstream ssh {
+ server 192.168.88.20:22;
+ }
+#定义转发mysql的3306端口
+ upstream mysql {
+ server 192.168.88.30:3306;
+ }
+ server {
+ listen 5555;
+ proxy_connect_timeout 3s;
+ proxy_timeout 300s;
+ proxy_pass ssh;
+ }
+
+ server {
+ listen 6666;
+ proxy_connect_timeout 3s;
+ proxy_timeout 3s;
+ proxy_pass mysql;
+ }
+}
+
+[root@lb01 ~]# nginx -t
+[root@lb01 ~]# setenforce 0
+[root@lb01 ~]# systemctl restart nginx
+```
+
+- 测试
+ - 略
+
+# 8. Keepalived 高可用基本概述
+
+ 一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快速的接管,对于访问的用户是无感知的。
+
+ 硬件通常使用 F5
+
+ 软件通常使用 keepalived
+
+ keepalived软件是基于VRRP协议实现的,VRRP虚拟路由冗余协议,主要用于解决单点故障问题
+
+## 8.1 VRRP原理
+
+- VRRP协议是一种容错的主备模式的协议,保证当主机的下一跳路由出现故障时,由另一台路由器来代替出现故障的路由器进行工作,通过VRRP可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信。
+- 虚拟路由器:VRRP组中所有的路由器,拥有虚拟的IP+MAC(00-00-5e-00-01-VRID)地址
+- 主路由器:虚拟路由器内部通常只有一台物理路由器对外提供服务,主路由器是由选举算法产生,对外提供各种网络功能。
+- 备份路由器:VRRP组中除主路由器之外的所有路由器,不对外提供任何服务,只接受主路由的通告,当主路由器挂掉之后,重新进行选举算法接替master路由器。
+- 选举机制
+ - 优先级
+ - 抢占模式下,一旦有优先级高的路由器加入,即成为Master
+ - 非抢占模式下,只要Master不挂掉,优先级高的路由器只能等待
+- 三种状态
+ - Initialize状态:系统启动后进入initialize状态
+ - Master状态
+ - Backup状态
+
+# 9. Keepalived高可用安装配置
+
+## 9.1 安装keepalived
+
+```bash
+[root@lb01 ~]# yum install -y keepalived
+[root@lb02 ~]# yum install -y keepalived
+```
+
+## 9.2 配置master
+
+- 找到配置文件
+
+```bash
+[root@lb02 ~]# rpm -qc keepalived
+/etc/keepalived/keepalived.conf
+/etc/sysconfig/keepalived
+```
+
+- 修改配置
+
+```bash
+[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
+global_defs { #全局配置
+ router_id lb01 #标识身份->名称
+}
+
+vrrp_instance VI_1 {
+ state MASTER #标识角色状态
+ interface ens33 #网卡绑定接口
+ virtual_router_id 50 #虚拟路由id
+ priority 150 #优先级
+ advert_int 1 #监测间隔时间
+ #use_vmac #使用虚拟mac地址,因为路由问题,可能导致原本的IP不可用
+ authentication { #认证
+ auth_type PASS #认证方式
+ auth_pass 1111 #认证密码
+ }
+ virtual_ipaddress {
+ 192.168.88.100 #虚拟的VIP地址
+ }
+}
+```
+
+## 9.3 配置backup
+
+```bash
+[root@lb02 ~]# vim /etc/keepalived/keepalived.conf
+global_defs {
+ router_id lb02
+}
+
+vrrp_instance VI_1 {
+ state BACKUP
+ interface ens33
+ virtual_router_id 50
+ priority 100
+ advert_int 1
+ authentication {
+ auth_type PASS
+ auth_pass 1111
+ }
+ virtual_ipaddress {
+ 192.168.88.100
+ }
+}
+```
+
+## 9.4 对比master与Backup的keepalived配置区别
+
+| Keepalived配置区别 | Master节点配置 | Backup节点配置 |
+| :------------------- | :------------- | :------------- |
+| route_id(唯一标识) | router_id lb01 | router_id lb02 |
+| state(角色状态) | state MASTER | state BACKUP |
+| priority(竞选优先级) | priority 150 | priority 100 |
+
+## 9.5 启动Master和Backup节点的keepalived
+
+```bash
+[root@lb01 ~]# systemctl start keepalived
+[root@lb01 ~]# systemctl enable keepalived
+
+[root@lb02 ~]# systemctl start keepalived
+[root@lb02 ~]# systemctl enable keepalived
+```
+
+# 10. 高可用keepalived抢占式与非抢占式
+
+- 由于节点1的优先级高于节点2,所以VIP在节点1上面
+
+```bash
+[root@lb01 ~]# ip addr |grep 192.168.88.100
+ inet 192.168.88.100/32 scope global ens33
+```
+
+- 关闭节点1的keepalived
+
+```bash
+[root@lb01 ~]# systemctl stop keepalived
+```
+
+- 节点2联系不上节点1,主动接管VIP
+
+```bash
+[root@lb02 ~]# ip addr |grep 192.168.88.100
+ inet 192.168.88.100/32 scope global ens33
+```
+
+- 此时重新启动Master上的keepalived,会发现VIP被强行抢占
+
+```bash
+[root@lb01 ~]# systemctl start keepalived
+[root@lb01 ~]# ip addr |grep 192.168.88.100
+ inet 192.168.88.100/32 scope global ens33
+```
+
+- 配置非抢占式
+
+ - 两个节点的state都必须配置为BACKUP
+ - 两个节点都必须加上配置 nopreempt
+ - 其中一个节点的优先级必须要高于另外一个节点的优先级。
+ - 两台服务器都角色状态启用nopreempt后,必须修改角色状态统一为BACKUP,唯一的区分就是优先级。
+
+```bash
+Master配置
+ vrrp_instance VI_1 {
+ state BACKUP
+ priority 150
+ nopreempt
+ }
+
+Backup配置
+ vrrp_instance VI_1 {
+ state BACKUP
+ priority 100
+ nopreempt
+ }
+```
+
+- 通过windows的arp去验证,是否会切换MAC地址
+
+```bash
+# 当前master在lb01上
+[root@lb01 ~]# ip addr |grep 192.168.88.100
+ inet 192.168.88.100/32 scope global ens33
+
+# windows查看mac地址
+C:\Users\Aaron>arp -a |findstr 192.168.88.100
+ 192.168.88.100 00-0c-29-bb-9a-bb 动态
+```
+
+- 关闭lb01的keepalive
+
+```bash
+[root@lb01 ~]# systemctl stop keepalived
+```
+
+- lb02接管vIP
+
+```bash
+[root@lb02 ~]# ip addr |grep 192.168.88.100
+ inet 192.168.88.100/32 scope global ens33
+```
+
+- 再次查看windows的mac地址
+
+```bash
+C:\Users\Aaron>arp -a |findstr 192.168.88.100
+ 192.168.88.100 00-0c-29-bb-9a-bb 动态
+```
+
+# 11. 高可用keepalived故障脑裂
+
+ 由于某些原因,导致两台keepalived高可用服务器在指定时间内,无法检测到对方的心跳,各自取得资源及服务的所有权,而此时的两台高可用服务器又都还活着。
+
+## 11.1 脑裂故障原因
+
+- 服务器网线松动等网络故障
+- 服务器硬件故障发生损坏现象而崩溃
+- 主备都开启firewalld防火墙
+
+## 11.2 脑裂故障现象
+
+- 正常情况下backup以监听为主,所以抓包会看到只有master在发送vrrp的数据包
+
+
+
+- 打开设备的防火墙,查看抓包情况,可以看到两台设备认为自己是master
+
+
+
+```bash
+[root@lb01 ~]# ip a |grep 192.168.88.100
+ inet 192.168.88.100/24 scope global secondary ens33
+
+[root@lb02 ~]# ip a |grep 192.168.88.100
+ inet 192.168.88.100/24 scope global secondary ens33
+```
+
+## 11.3 解决脑裂故障方案
+
+- 如果发生脑裂,则随机kill掉一台即可
+- 在backup上编写检测脚本, 测试如果能ping通master并且backup节点还有vIP的话则认为产生了脑裂
+
+```bash
+[root@lb02 ~]# vim check_split_brain.sh
+#!/bin/sh
+vip=192.168.88.100
+lb01_ip=192.168.88.10
+while true;do
+ ping -c 2 $lb01_ip &>/dev/null
+ if [ $? -eq 0 -a `ip add|grep "$vip"|wc -l` -eq 1 ];then
+ echo "ha is split brain.warning."
+ else
+ echo "ha is ok"
+ fi
+sleep 5
+done
+```
+
+# 12. 高可用keepalived与nginx
+
+ Nginx默认监听在所有的IP地址上,VIP会飘到一台节点上,相当于那台nginx多了VIP这么一个网卡,所以可以访问到nginx所在机器
+
+ 但是.....如果nginx宕机,会导致用户请求失败,但是keepalived没有挂掉不会进行切换,所以需要编写一个脚本检测Nginx的存活状态,如果不存活则kill掉keepalived
+
+```bash
+[root@lb01 ~]# vim check_web.sh
+#!/bin/sh
+nginxpid=$(ps -C nginx --no-header|wc -l)
+
+#1.判断Nginx是否存活,如果不存活则尝试启动Nginx
+if [ $nginxpid -eq 0 ];then
+ systemctl start nginx
+ sleep 3
+ #2.等待3秒后再次获取一次Nginx状态
+ nginxpid=$(ps -C nginx --no-header|wc -l)
+ #3.再次进行判断, 如Nginx还不存活则停止Keepalived,让地址进行漂移,并退出脚本
+ if [ $nginxpid -eq 0 ];then
+ systemctl stop keepalived
+ fi
+fi
+```
+
+## 12.1 在lb01主机的keepalived配置文件中调用此脚本
+
+```bash
+[root@lb01 ~]# vim /etc/keepalived/keepalived.conf
+global_defs {
+ router_id lb01
+}
+
+#每5秒执行一次脚本,脚本执行内容不能超过5秒,否则会中断再次重新执行脚本
+vrrp_script check_web {
+ script "/root/check_web.sh"
+ interval 5
+}
+
+vrrp_instance VI_1 {
+ state MASTER
+ interface ens33
+ virtual_router_id 50
+ priority 150
+ advert_int 1
+ authentication {
+ auth_type PASS
+ auth_pass 1111
+ }
+ virtual_ipaddress {
+ 192.168.88.100
+ }
+}
+
+#调用并运行脚本
+track_script {
+ check_web
+}
+```
+
+# 13. 集群和分布式
+
+系统性能扩展方式:
+
+- Scale UP:垂直扩展,向上扩展,增强,性能更强的计算机运行同样的服务,成本高。
+- Scale Out:水平扩展,向外扩展,增加设备,并行地运行多个服务调度分配问题,Cluster
+
+垂直扩展不再提及:
+
+- 随着计算机性能的增长,其价格会成倍增长
+- 单台计算机的性能是有上限的,不可能无限制地垂直扩展
+- 多核CPU意味着即使是单台计算机也可以并行的。
+
+## 13.1 集群 Cluster
+
+Cluster:集群,为解决某个特定问题将多台计算机组合起来形成的单个系统
+
+Cluster分为三种类型:
+
+- LB:Load Balancing,负载均衡。调度负载,按照算法调度。
+- HA:High Availiablity,高可用,避免SPOF(single Point Of failure)(单点失败)
+ - MTBF:Mean Time Between Failure 平均无故障时间
+ - MTTR:Mean Time To Restoration( repair)平均恢复前时间
+ - A=MTBF/(MTBF+MTTR) (0,1):99%,99.5%,99.9%,99.99%,99.999%
+- HPC:High-performance computing,高性能 www.top500.org
+
+## 13.2 分布式系统
+
+分布式存储: Ceph,GlusterFS,FastDFS,MogileFS
+分布式计算:hadoop,Spark
+分布式常见应用
+分布式应用-服务按照功能拆分,使用微服务
+分布式静态资源–静态资源放在不同的存储集群上
+分布式数据和存储–使用key-value缓存系统
+分布式计算–对特殊业务使用分布式计算,比如Hadoop集群
+
+## 13.3 集群和分布式
+
+集群:同一个业务系统,部署在多台服务器上。集群中,每一台服务器实现的功能没有差别,数据和代
+码都是一样的
+
+分布式:一个业务被拆成多个子业务,或者本身就是不同的业务,部署在多台服务器上。分布式中,每
+ 一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务。
+
+ 分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
+ 对于大型网站,访问用户很多,实现一个群集,在前面部署一个负载均衡服务器,后面几台服务器完成
+ 同一业务。如果有用户进行相应业务访问时,负载均衡器根据后端哪台服务器的负载情况,决定由给哪一台去完成响应,并且一台服务器垮了,其它的服务器可以顶上来。分布式的每一个节点,都完成不同的业务,如果一个节点垮了,那这个业务可能就会失败。
+
+## 13.4 集群设计原则
+
+可扩展性—集群的横向扩展能力。小型机横向扩展小,面临淘汰
+可用性—无故障时间(SLA)
+性能—访问响应时间
+容量—单位时间内的最大并发吞吐量(C10K 并发问题) 。LVS内核级,并发好。
+
+## 13.5 集群设计实现
+
+### 13.5.1 基础设施层面
+
+提升硬件资源性能—从入口防火墙到后端web server均使用更高性能的硬件资源
+多域名—DNS 轮询A记录解析。指向不同IP 访问入口增多
+多入口—将A记录解析到多个公网IP入口
+多机房—同城+异地容灾
+CDN(Content Delivery Network)—基于GSLB(Global Server Load Balance)实现全局负载均衡,如:DNS
+就近分配地址,提高效率
+
+### 13.5.2 业务层面
+
+分层:安全层、负载层、静态层、动态层、(缓存层、存储层)持久化与非持久化
+分割:基于功能分割大业务为小服务
+分布式:对于特殊场景的业务,使用分布式计算
+
+## 13.6 LB Cluster 负载均衡集群
+
+### 13.6.1 按实现方式划分
+
+- 硬件(大公司)
+ - F5 Big-IP
+ - Citrix Netscaler
+ - A10
+
+- 软件(小公司)
+ - lvs:Linux Virtual Server,阿里四层SLB (Server Load Balance)使用下四层功能:物理层 数据链路层
+ - nginx:支持七层调度,阿里七层SLB使用Tengine
+ - haproxy:支持七层调度
+ - ats:Apache Traffic Server,yahoo捐助给apache
+ - perlbal:Perl 编写
+ - pound
+
+### 13.6.2 基于工作的协议层次划分
+
+- 传输层(通用):DNAT和DPORT
+ - LVS:Linux Virtual Server
+ - nginx:stream
+ - haproxy:mode tcp
+
+- 应用层(专用):针对特定协议,常称为 proxy server
+ - http:nginx, httpd, haproxy(mode http), …
+ - fastcgi:nginx, httpd, …
+ - mysql:mysql-proxy, …
+
+### 13.6.3 负载均衡的会话保持
+
+- session sticky:同一用户调度固定服务器
+ - Source IP:LVS sh算法(对某一特定服务而言)
+ - Cookie
+- session replication:每台服务器拥有全部session
+ - session multicast cluster (内存消耗大)
+- session server:专门的session服务器
+ - Memcached,Redis (只放session,共享)也存在单点失败,即也要做集群哨兵机制
+
+## 13.7 HA 高可用集群实现
+
+keepalived:vrrp协议
+Ais:应用接口规范
+heartbeat
+cman+rgmanager(RHCS)
+coresync_pacemaker
+
+# 14. Linux Virtual Server简介
+
+## 14.1 LVS介绍
+
+- LVS:Linux Virtual Server,负载调度器,内核集成,章文嵩(花名 正明), 阿里的四层SLB(Server Load Balance)是基于LVS+keepalived实现。
+- LVS 官网:http://www.linuxvirtualserver.org/
+- LVS 相关术语
+ - VS: Virtual Server,负责调度
+ - RS: Real Server,负责真正提供服务
+
+## 14.2 LVS工作原理
+
+ VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行“处理”
+
+ 查看内核支持LVS
+
+```bash
+[root@localhost ~]# grep -i -C 10 ipvs /boot/config-3.10.0-957.el7.x86_64
+```
+
+## 14.3 LVS集群体系架构
+
+
+
+## 14.4 LVS 功能及组织架构
+
+下面摘自于阿里云:https://help.aliyun.com/document_detail/27543.html?spm=5176.21213303.J_6028563670.7.505a3edaQq9WLJ&scm=20140722.S_help%40%40%E6%96%87%E6%A1%A3%40%4027543.S_0.ID_27543-OR_s%2Bhelpproduct-V_1-P0_0
+
+负载均衡的应用场景为高访问量的业务,提高应用程序的可用性和可靠性。
+
+## 14.5 应用于高访问量的业务
+
+如果您的应用访问量很高,您可以通过配置监听规则将流量分发到不同的云服务器ECS(Elastic Compute Service)实例上。此外,您可以使用会话保持功能将同一客户端的请求转发到同一台后端ECS,提高访问效率。
+
+## 14.6 扩展应用程序
+
+您可以根据业务发展的需要,随时添加和移除ECS实例来扩展应用系统的服务能力,适用于各种Web服务器和App服务器。
+
+## 14.7 消除单点故障
+
+您可以在CLB实例下添加多台ECS实例。当其中一部分ECS实例发生故障后,CLB会自动屏蔽故障的ECS实例,将请求分发给正常运行的ECS实例,保证应用系统仍能正常工作。
+
+## 14.8 同城容灾 (多可用区容灾)
+
+为了提供更加稳定可靠的CLB服务,CLB已在各地域部署了多可用区以实现同地域容灾。当主可用区出现机房故障或不可用时,CLB仍然有能力在非常短的时间内(大约30s中断)切换到另外一个备可用区恢复服务能力;当主可用区恢复时,CLB同样会自动切换到主可用区提供服务。
+
+使用CLB时,您可以将CLB实例部署在支持多可用区的地域以实现同城容灾。此外,建议您结合自身的应用需要,综合考虑后端服务器的部署。如果您的每个可用区均至少添加了一台ECS实例,那么此种部署模式下的CLB服务的效率是最高的。
+
+如下图所示,在CLB实例下绑定不同可用区的ECS实例。正常情况下,用户访问流量将同时转发至主、备可用区内的ECS实例;当可用区A发生故障时,用户访问流量将只转发至备可用区内的ECS实例。此种部署既可以避免因为单个可用区的故障而导致对外服务的不可用,也可以通过不同产品间可用区的选择来降低延迟。
+
+
+
+如果您采取如下图所示的部署方案,即在CLB实例的主可用区下绑定多台ECS实例,而在备可用区没有任何ECS实例。正常情况下,用户访问流量将只转发至主可用区内的ECS实例,比较于上图,流量传输延时低;当可用区A发生故障时会造成业务中断,因为备可用区没有ECS实例来接收请求。这样的部署方式很明显是以牺牲高可用性为代价来获取低延时。
+
+
+
+## 14.9 跨地域容灾
+
+您可以在不同地域下部署CLB实例,并分别挂载相应地域内不同可用区的ECS。上层利用云解析做智能DNS,将域名解析到不同地域的CLB实例服务地址下,可实现全局CLB。当某个地域出现不可用时,暂停对应解析即可实现所有用户访问不受影响。
+
+
+
+## 14.10 LVS应用场景
+
+### 14.10.1 音视频/游戏等大并发流量场景
+
+ 音视频/游戏等行业经常面临突发访问,海量流量,后端服务压力大。如短视频/长视频/直播/在校教育/游戏等业务中,由于服务端与用户端之间需要实时大量的互动,因此,用户流量非常大,而音视频业务的波峰波谷效应明显,这对整个系统的性能、弹性、稳定性和可用性带来了巨大的挑战,需要使用负载均衡进行流量分发
+
+
+
+### 14.10.2 零售/金融/企业等弹性高可靠场景
+
+ 新零售新金融业务变化快,新业务上线、老业务调整时常发生,大促大型活动常态化;因此,对即开即用网络,快速交付能力,弹性伸缩能力,安全可靠、灵活计费等需求显著,需要使用负载均衡搭建高可靠架构。
+
+
+
+### 14.10.3 云原生网络应用场景
+
+ 随着云原生逐步成熟,互联网/金融/企业等诸多行业新建业务时选择云原生部署,或对现有业务进行云原生化改造。无论是使用阿里云ACK/ASK/SAE还是开源K8S,云原生网络均可用到负载均衡服务来实现流量调度。
+
+
+
+### 14.10.4 跨地域网络应用场景
+
+ 跨地域跨可用区的容灾方案。互联网/金融/企业等业务逐步遍及全球,需要将不同地域用户智能调度访问到相应的业务系统,为了降本增效,线下IDC业务需要与云上业务互通,需要使用负载均衡构建跨地域或混合云容灾架构。
+
+
+
+## 14.11 LVS集群类型中的术语
+
+VS:Virtual Server,Director Server(DS), Dispatcher(调度器),Load Balancer
+RS:Real Server(lvs), upstream server(nginx)上游服务器, backend server(haproxy)
+CIP:Client IP
+VIP:Virtual serve IP VS外网的IP
+DIP:Director IP VS内网的IP
+RIP:Real server IP
+访问流程:CIP <–> VIP == DIP <–> RIP
+
+# 15. LVS 工作模式和相关命令
+
+## 15.1 LVS集群的工作模式
+
+lvs-nat:修改请求报文的目标IP,多目标IP的DNAT
+lvs-dr:操纵封装新的MAC地址。MAC头的修改
+lvs-tun:在原请求IP报文之外新加一个IP首部。
+lvs-fullnat:修改请求报文的源和目标IP
+
+### 15.1.1 LVS的NAT模式
+
+
+
+lvs-nat:本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发
+
+- RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP
+- 请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈
+- 支持端口映射,可修改请求报文的目标PORT
+- VS必须是Linux系统,RS可以是任意OS系统
+
+
+
+
+
+### 15.1.2 LVS的DR模式
+
+
+
+ LVS-DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部
+进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源
+IP/PORT,以及目标IP/PORT均保持不变
+
+
+
+DR模式的特点
+
+- Director和各RS都配置有VIP
+- 确保前端路由器将目标IP为VIP的请求报文发往Director三种方法
+
+在前端网关做静态绑定VIP和Director的MAC地址
+
+此方法一般不使用,过于固定
+
+在RS上使用arptables工具
+
+```bash
+arptables -A IN -d $VIP -j DROP
+arptables -A OUT -s $VIP -j mangle --mangle-ip-s $RIP
+```
+
+在RS上修改内核参数以限制arp通告及应答级别
+
+```bash
+/proc/sys/net/ipv4/conf/all/arp_ignore
+/proc/sys/net/ipv4/conf/all/arp_announce
+```
+
+- RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director
+- RS和Director要在同一个物理网络
+- 请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client
+- 不支持端口映射(端口不能修改)
+- RS可使用大多数OS系统
+
+### 15.1.3 LVS的TUN模式
+
+
+
+ 转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)
+
+
+
+TUN模式特点
+
+- DIP, VIP, RIP可以是公网地址
+- RS的网关一般不能指向DIP
+- 请求报文要经由Director,但响应不经由Director
+- 不支持端口映射
+- RS的OS须支持隧道功能
+
+### 15.1.4 LVS的FULLNAT模式
+
+
+
+- 通过同时修改请求报文的源IP地址和目标IP地址进行转发
+- CIP --> DIP
+- VIP --> RIP
+
+- fullnat模式特点:
+ - VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP
+ - RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client
+ - 请求和响应报文都经由Director
+ - 支持端口映射
+ - 注意:此类型kernel默认不支持
+
+### 15.1.5 LVS工作模式总结和比较
+
+| | NAT | TUN | DR |
+| ------------------- | ------------- | ---------- | -------------- |
+| Real server | any | Tunneling | Non-arp device |
+| Real server network | private | LAN/WAN | LAN |
+| Real Server number | low(10-20) | High(100) | High(100) |
+| Real server gateway | load balancer | own router | own router |
+| 优点 | 端口转换 | WAN | 性能最好 |
+| 缺点 | 性能瓶颈 | 支持隧道 | 不支持跨网段 |
+
+- lvs-nat与lvs-fullnat:
+ - 请求和响应报文都经由Director
+ - lvs-nat:RIP的网关要指向DIP
+ - lvs-fullnat:RIP和DIP未必在同一IP网络,但要能通信
+- lvs-dr与lvs-tun:
+ - 请求报文要经由Director,但响应报文由RS直接发往Client
+ - lvs-dr:通过封装新的MAC首部实现,通过MAC网络转发
+ - lvs-tun:通过在原IP报文外封装新IP头实现转发,支持远距离通信
+
+## 15.2 LVS调试算法
+
+ipvs scheduler:根据其调度时是否考虑各RS当前的负载状态
+分为两种:静态方法和动态方法
+
+### 15.2.1 静态方法
+
+- 仅根据算法本身进行调度
+ - RR:roundrobin,轮询 不考虑机器的性能好坏,轮询调度
+ - WRR:Weighted RR,加权轮询 权重越高,优先级高,调度更多资源给它 优先级高
+ - SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定
+ - DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
+
+### 15.2.2 动态方法
+
+主要根据每RS当前的负载状态及调度算法进行调度Overhead=value 较小的RS将被调度
+
+- LC:least connections 适用于长连接应用(最少连接 )
+ - `Overhead=activeconns *256+inactiveconns`
+
+- WLC:Weighted LC,默认调度方法(加权最少连接 )
+ - `Overhead=(activeconns * 256+inactiveconns)/weight`
+
+- SED:Shortest Expection Delay,初始连接高权重优先(最少期望延迟)
+ - `Overhead=(activeconns+1)*256/weight`
+
+- NQ:Never Queue,第一轮均匀分配,后续SED(从不排队调度方法)
+
+- LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理
+
+- LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS
+
+### 15.2.3 内核版本 4.15版本后新增调度算法
+
+- FO(Weighted Fail Over)调度算法,在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F_OVERLOAD标志)的且权重最高的真实服务器,进行调度。方便调式上下线。
+
+- OVF(Overflow-connection)调度算法,基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值位置,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件:
+ - 未过载(未设置IP_VS_DEST_F_OVERLOAD标志)
+ - 真实服务器当前的活动连接数量小于其权重值
+ - 其权重值不为零
+
+## 15.3 LVS 相关软件
+
+### 15.3.1 程序包
+
+- Unit File: ipvsadm.service
+- 主程序:/usr/sbin/ipvsadm
+- 规则保存工具:/usr/sbin/ipvsadm-save
+- 规则重载工具:/usr/sbin/ipvsadm-restore
+- 配置文件:/etc/sysconfig/ipvsadm-config
+
+```bash
+[root@localhost ~]# yum -y install ipvsadm
+[root@localhost ~]# cat /usr/lib/systemd/system/ipvsadm.service
+[Unit]
+Description=Initialise the Linux Virtual Server
+After=syslog.target network.target
+
+[Service]
+Type=oneshot
+ExecStart=/bin/bash -c "exec /sbin/ipvsadm-restore < /etc/sysconfig/ipvsadm"
+ExecStop=/bin/bash -c "exec /sbin/ipvsadm-save -n > /etc/sysconfig/ipvsadm"
+ExecStop=/sbin/ipvsadm -C
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+```
+
+### 15.3.2 ipvsadm 命令
+
+- ipvsadm核心功能:
+ - 集群服务管理:增、删、改
+ - 集群服务的RS管理:增、删、改
+ - 查看
+
+```bash
+#管理集群服务
+ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
+[--pe persistence_engine] [-b sched-flags]
+ipvsadm -A #创建集群
+ipvsadm -E #修改集群
+ipvsadm -D -t|u|f service-address #删除
+ipvsadm –C #清空
+ipvsadm –R #重载
+ipvsadm -S [-n] #保存
+ipvsadm -L #查看
+
+#管理集群中的RS
+ipvsadm -a|e -t|u|f service-address -r server-address [options]
+ipvsadm -d -t|u|f service-address -r server-address
+ipvsadm -L|l [options]
+ipvsadm -Z [-t|u|f service-address] #清空计数器
+
+#保存规则
+‐S
+# ipvsadm ‐S > /path/to/somefile
+载入此前的规则:
+‐R
+# ipvsadm ‐R < /path/form/somefile
+```
+
+- 说明
+
+```bash
+service-address:
+
+-t|u|f:
+ -t: TCP协议的端口,VIP:TCP_PORT 如:-t 192.168.88.20:80
+ -u: UDP协议的端口,VIP:UDP_PORT 如:-u 192.168.88.20:80
+ -f:firewall MARK,标记,一个数字
+[-s scheduler]:指定集群的调度算法,默认为wlc
+
+server-address:
+
+rip[:port] 如省略port,不作端口映射
+选项:
+ lvs类型:
+ -g: gateway, dr类型,默认
+ -i: ipip, tun类型
+ -m: masquerade, nat类型
+ -w weight:权重
+```
+
+- 举例
+
+```bash
+ipvsadm -A -t 192.168.88.100:80 -s wrr # 创建集群
+ipvsadm -D -t 192.168.88.100:80 # 删除集群
+
+ipvsadm -a -t 192.168.88.100:80 -r 192.168.88.20:8080 -m -w 3
+# 往集群中添加RS,并且设置nat,配置权重为3
+ipvsadm -d -t 192.168.88.100:80 -r 192.168.88.20:8080
+# 删除RS
+```
+
+- 查看
+
+```bash
+ipvsadm -L|l [options]
+ –numeric, -n:以数字形式输出地址和端口号
+ –exact:扩展信息,精确值
+ –connection,-c:当前IPVS连接输出
+ –stats:统计信息
+ –rate :输出速率信息
+```
+
+# 16. LVS实战案例
+
+## 16.1 LVS-NAT模式案例
+
+
+
+实验环境说明:
+
+LVS:两张网卡,一张nat网卡做为vIP与客户端建立连接,一张仅主机网卡用于对内部服务器的连接
+
+RS1和RS2:两个RS的网卡都使用仅主机的网卡,并且网关指向LVS的仅主机网卡
+
+- 开启LVS流量转发功能,并且配置NAT
+
+```bash
+[root@lvs ~]# vim /etc/sysctl.conf
+net.ipv4.ip_forward = 1
+[root@lvs ~]# sysctl -p
+net.ipv4.ip_forward = 1
+
+[root@lvs ~]# iptables -t nat -A POSTROUTING -s 192.168.153.0/24 -j MASQUERADE
+[root@lvs ~]# iptables -t nat -L -n
+```
+
+
+
+- 先搭建web服务器
+
+```bash
+[root@rs1 ~]# yum -y install httpd
+[root@rs1 ~]# systemctl start httpd
+[root@rs1 ~]# systemctl enable httpd
+[root@rs1 ~]# echo "RS1 ..." > /var/www/html/index.html
+[root@rs1 ~]# firewall-cmd --add-service=http
+[root@rs1 ~]# firewall-cmd --add-service=http --permanent
+
+[root@rs2 ~]# yum -y install httpd
+[root@rs2 ~]# systemctl start httpd
+[root@rs2 ~]# systemctl enable httpd
+[root@rs2 ~]# echo "RS2 ..." > /var/www/html/index.html
+[root@rs2 ~]# firewall-cmd --add-service=http
+[root@rs2 ~]# firewall-cmd --add-service=http --permanent
+```
+
+- 配置LVS
+
+```bash
+[root@lvs ~]# ipvsadm -A -t 192.168.88.10:80 -s rr
+[root@lvs ~]# ipvsadm -a -t 192.168.88.10:80 -r 192.168.153.20:80 -m
+[root@lvs ~]# ipvsadm -a -t 192.168.88.10:80 -r 192.168.153.30:80 -m
+[root@lvs ~]# ipvsadm -L -n
+IP Virtual Server version 1.2.1 (size=4096)
+Prot LocalAddress:Port Scheduler Flags
+ -> RemoteAddress:Port Forward Weight ActiveConn InActConn
+TCP 192.168.88.100:80 rr
+ -> 192.168.153.20:80 Masq 1 0 0
+ -> 192.168.153.30:80 Masq 1 0 0
+```
+
+- 验证结果
+
+
+
+
+
+- 抓包可以观察到客户端都是与LVS进行通信,LVS对流量进行NAT
+
+
+
+## 16.2 LVS-DR模式案例
+
+
+
+- 做这个实验之前,需要清空LVS之前配置的NAT规则
+
+```bash
+# 由于我们后面做实验要用到ifconfig命令,该命令需要安装net-tools工具。所以我们趁现在有网,可以先安装一下,三台机器都需要安装
+[root@lvs ~]# yum install -y net-tools
+[root@lvs ~]# iptables -t nat -F
+```
+
+- 修改RS1和RS2的网关地址
+
+```bash
+[root@rs1 ~]# ip route
+default via 192.168.153.2 dev ens33 proto static metric 100
+
+[root@rs2 ~]# ip route
+default via 192.168.153.2 dev ens33 proto static metric 100
+```
+
+- 在RS上修改内核参数以限制arp通告及应答级别
+
+```bash
+[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
+[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
+
+[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
+[root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
+```
+
+- 给RS1和RS2设置VIP 192.168.153.100
+
+```bash
+[root@rs1 ~]# vim rs.sh
+#!/bin/bash
+vip=192.168.153.100/32
+ifconfig lo:1 $vip
+echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
+echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
+echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
+echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
+
+[root@rs1 ~]# . rs.sh
+# 在RS2上也需要执行
+```
+
+- 配置LVS服务器
+
+```bash
+[root@lvs ~]# ifconfig lo:1 192.168.153.100/32
+[root@lvs ~]# ipvsadm -A -t 192.168.153.100:80 -s rr
+[root@lvs ~]# ipvsadm -a -t 192.168.153.100:80 -r 192.168.153.20
+[root@lvs ~]# ipvsadm -a -t 192.168.153.100:80 -r 192.168.153.30
+[root@lvs ~]# ipvsadm -Ln
+IP Virtual Server version 1.2.1 (size=4096)
+Prot LocalAddress:Port Scheduler Flags
+ -> RemoteAddress:Port Forward Weight ActiveConn InActConn
+TCP 192.168.153.100:80 rr
+ -> 192.168.153.20:80 Route 1 0 0
+ -> 192.168.153.30:80 Route 1 0 0
+```
+
+- 验证,当多次访问192.168.153.100的时候可以得到不同的主机回复
+
+
+
+
+
+# 17. HAProxy介绍
+
+ HAProxy是法国开发者威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件,是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计,目前最新TLS版本为2.0
+
+历史版本:
+
+- 历史版本更新功能:1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2-dev
+- 1.8:多线程,HTTP/2缓存……
+- 1.7:服务器动态配置,多类型证书……
+- 1.6:DNS解析支持,HTTP连接多路复用……
+- 1.5:开始支持SSL,IPV6,会话保持……
+
+从2013年HAProxy 分为社区版和企业版,企业版将提供更多的特性和功能以及全天24小时的技术支持等服务。
+
+## 17.1 企业版
+
+企业版网站:https://www.haproxy.com/
+
+
+
+## 17.2 社区版
+
+社区版网站:http://www.haproxy.org/
+
+github:https://github.com/haproxy
+
+
+
+## 17.3 版本对比
+
+| 功能 | 社区版 | 企业版 |
+| ----------------------------------------- | ------ | ------ |
+| 高级HTTP / TCP负载平衡和持久性 | 支持 | 支持 |
+| 高级健康检查 | 支持 | 支持 |
+| 应用程序加速 | 支持 | 支持 |
+| 高级安全特性 | 支持 | 支持 |
+| 高级管理 | 支持 | 支持 |
+| HAProxy Dev Branch新功能 | | 支持 |
+| 24*7 支持服务 | | 支持 |
+| 实时仪表盘 | | 支持 |
+| VRRP和Route Health Injection HA工具 | | 支持 |
+| ACL,映射和TLS票证密钥同步 | | 支持 |
+| 基于应用程序的高级DDoS和Bot保护(自动保护) | | 支持 |
+| Bot(机器人)监测 | | 支持 |
+| Web应用防火墙 | | 支持 |
+| HTTP协议验证 | | 支持 |
+| 实时集群追踪 | | 支持 |
+
+## 17.4 HAProxy功能
+
+
+
+## 17.5 支持功能
+
+- TCP 和 HTTP反向代理
+- SSL/TSL服务器
+- 可以针对HTTP请求添加cookie,进行路由后端服务器
+- 可平衡负载至后端服务器,并支持持久连接
+- 支持所有主服务器故障切换至备用服务器
+- 支持专用端口实现监控服务
+- 支持停止接受新连接请求,而不影响现有连接
+- 可以在双向添加,修改或删除HTTP报文首部
+- 响应报文压缩
+- 支持基于pattern实现连接请求的访问控制
+- 通过特定的URI为授权用户提供详细的状态信息
+- 支持http反向代理
+- 支持动态程序的反向代理
+- 支持基于数据库的反向代理
+
+## 17.6 不具备的功能
+
+- 正向代理--squid,nginx
+- 缓存代理--varnish
+- web服务--nginx、tengine、apache、php、tomcat
+- UDP--目前不支持UDP协议
+- 单机性能--相比LVS性能较差
+
+# 18. 编译安装HAProxy
+
+- 编译安装HAProxy 2.0 LTS版本,更多源码包下载地址:http://www.haproxy.org/download/
+- centos7自带的源中yum安装的版本是较老的1.5的版本
+
+## 18.1 解决lua环境
+
+ HAProxy 支持基于lua实现功能扩展,lua是一种小巧的脚本语言,于1993年由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组开发,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
+
+Lua 官网:www.lua.org
+
+- Lua 应用场景
+
+ - 游戏开发
+ - 独立应用脚本
+ - Web 应用脚本
+ - 扩展和数据库插件,如MySQL Proxy
+ - 安全系统,如入侵检测系统
+
+### 18.1.1 Centos 基础环境
+
+参考链接:http://www.lua.org/start.html
+
+
+
+ 由于CentOS7 之前版本自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy,过程如下
+
+- 当前系统版本
+
+```bash
+[root@localhost ~]# lua -v
+Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
+```
+
+- 安装基础命令及编译依赖环境
+
+```bash
+[root@localhost ~]# yum -y install gcc readline-devel
+[root@localhost ~]# wget http://www.lua.org/ftp/lua-5.3.5.tar.gz
+[root@localhost ~]# tar xvf lua-5.3.5.tar.gz -C /usr/local/src
+[root@localhost ~]# cd /usr/local/src/lua-5.3.5
+[root@localhost lua-5.3.5]# make linux test
+```
+
+- 查看编译安装的版本
+
+```bash
+[root@localhost lua-5.3.5]# src/lua -v
+Lua 5.3.5 Copyright (C) 1994-2018 Lua.org, PUC-Rio
+```
+
+## 18.2 编译安装HAProxy
+
+- HAProxy 2.0以上版本编译参数
+
+```bash
+[root@localhost ~]# yum -y install gcc openssl-devel pcre-devel systemd-devel
+[root@localhost ~]# wget http://www.haproxy.org/download/2.1/src/haproxy-2.1.3.tar.gz
+[root@localhost ~]# tar xvf haproxy-2.1.3.tar.gz -C /usr/local/src
+[root@localhost ~]# cd /usr/local/src/haproxy-2.1.3/
+[root@localhost haproxy-2.1.3]# cat README
+```
+
+- 参考INSTALL文件进行编译安装
+
+```bash
+[root@localhost haproxy-2.1.3]# make -j 2 ARCH=x86_64 TARGET=linux-glibc \
+USE_PCRE=1 \
+USE_OPENSSL=1 \
+USE_ZLIB=1 \
+USE_SYSTEMD=1 \
+USE_LUA=1 \
+LUA_INC=/usr/local/src/lua-5.3.5/src/ \
+LUA_LIB=/usr/local/src/lua-5.3.5/src/
+[root@localhost haproxy-2.1.3]# make install PREFIX=/apps/haproxy
+[root@localhost haproxy-2.1.3]# ln -s /apps/haproxy/sbin/haproxy /usr/sbin/
+```
+
+- 查看生成的文件
+
+```bash
+[root@localhost ~]# tree -C /apps/haproxy/
+/apps/haproxy/
+├── doc
+│ └── haproxy
+│ ├── 51Degrees-device-detection.txt
+│ ├── architecture.txt
+│ ├── close-options.txt
+│ ├── configuration.txt
+│ ├── cookie-options.txt
+│ ├── DeviceAtlas-device-detection.txt
+│ ├── intro.txt
+│ ├── linux-syn-cookies.txt
+│ ├── lua.txt
+│ ├── management.txt
+│ ├── netscaler-client-ip-insertion-protocol.txt
+│ ├── network-namespaces.txt
+│ ├── peers.txt
+│ ├── peers-v2.0.txt
+│ ├── proxy-protocol.txt
+│ ├── regression-testing.txt
+│ ├── seamless_reload.txt
+│ ├── SOCKS4.protocol.txt
+│ ├── SPOE.txt
+│ └── WURFL-device-detection.txt
+├── sbin
+│ └── haproxy
+└── share
+ └── man
+ └── man1
+ └── haproxy.1
+
+6 directories, 22 files
+```
+
+## 18.3 验证HAProxy版本
+
+```bash
+[root@localhost ~]# which haproxy
+/usr/sbin/haproxy
+[root@localhost ~]# haproxy -v
+HA-Proxy version 2.1.3 2020/02/12 - https://haproxy.org/
+Status: stable branch - will stop receiving fixes around Q1 2021.
+Known bugs: http://www.haproxy.org/bugs/bugs-2.1.3.html
+
+[root@localhost ~]# haproxy -vv
+HA-Proxy version 2.1.3 2020/02/12 - https://haproxy.org/
+Status: stable branch - will stop receiving fixes around Q1 2021.
+Known bugs: http://www.haproxy.org/bugs/bugs-2.1.3.html
+Build options :
+ TARGET = linux-glibc
+ CPU = generic
+ CC = gcc
+ CFLAGS = -m64 -march=x86-64 -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-old-style-declaration -Wno-ignored-qualifiers -Wno-clobbered -Wno-missing-field-initializers -Wtype-limits
+ OPTIONS = USE_PCRE=1 USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_SYSTEMD=1
+
+Feature list : +EPOLL -KQUEUE -MY_EPOLL -MY_SPLICE +NETFILTER +PCRE -PCRE_JIT -PCRE2 -PCRE2_JIT +POLL -PRIVATE_CACHE +THREAD -PTHREAD_PSHARED -REGPARM -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H -VSYSCALL +GETADDRINFO +OPENSSL +LUA +FUTEX +ACCEPT4 -MY_ACCEPT4 +ZLIB -SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL +SYSTEMD -OBSOLETE_LINKER +PRCTL +THREAD_DUMP -EVPORTS
+
+Default settings :
+ bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
+
+Built with multi-threading support (MAX_THREADS=64, default=4).
+Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
+Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
+OpenSSL library supports TLS extensions : yes
+OpenSSL library supports SNI : yes
+OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
+Built with Lua version : Lua 5.3.5
+Built with network namespace support.
+Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
+Built with PCRE version : 8.32 2012-11-30
+Running on PCRE version : 8.32 2012-11-30
+PCRE library supports JIT : no (USE_PCRE_JIT not set)
+Encrypted password support via crypt(3): yes
+Built with zlib version : 1.2.7
+Running on zlib version : 1.2.7
+Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
+
+Available polling systems :
+ epoll : pref=300, test result OK
+ poll : pref=200, test result OK
+ select : pref=150, test result OK
+Total: 3 (3 usable), will use epoll.
+
+Available multiplexer protocols :
+(protocols marked as
+
+```bash
+[root@localhost ~]# awk -F":" '{print $1}' /etc/passwd
+[root@localhost ~]# awk -F":" '{print $1 $3}' /etc/passwd
+[root@localhost ~]# awk -F":" '{print $1 " " $3}' /etc/passwd
+[root@localhost ~]# awk -F":" '{print "username:"$1 "\t tuid:" $3}' /etc/passwd
+```
+
+-F参数:指定分隔符,可指定一个或多个
+
+print 后面做字符串的拼接
+
+## 6.3 案例
+
+### 6.3.1 查看文件内容
+
+只查看test.txt文件(100行)内第20到第30行的内容**(企业面试)**
+
+```bash
+[root@localhost ~]# seq 100 > test.txt
+[root@localhost ~]# awk '{if(NR>=20 && NR<=30) print $1}' test.txt
+# NR为内置变量,表示行号,从1开始
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+```
+
+### 6.3.2 过滤指定字符
+
+已知文本内容如下:
+
+```bash
+[root@localhost ~]# cat testfile
+I am nls, my qq is 12345678
+```
+
+从该文本中过滤出姓名和qq号,要求最后输出结果为:Name: QQ
+
+```bash
+[root@localhost ~]# awk -F '[ ,]' '{print "Name: " $3, "\nQQ: " $8}' testfile
+Name: nls
+QQ: 12345678
+```
+
+## 6.4 BEGIN 和 END 模块
+
+1. **BEGIN 模块**:
+ - `BEGIN` 模块是在 awk 开始处理输入数据之前执行的。
+ - 它通常用于初始化一些变量或者打印一些提示信息。
+ - 比如在处理文件之前,先打印一行 "Processing the file..."。
+2. **END 模块**:
+ - `END` 模块是在 awk 处理完所有输入数据之后执行的。
+ - 它通常用于输出一些最终的统计信息或者结果。
+ - 比如在处理完文件后,打印出总共处理了多少行数据。
+
+### 6.4.1 案例一:统计当前系统中存在的账户数量
+
+```bash
+[root@localhost ~]# awk 'BEGIN {count=0;print "[start] user count is: "count}{count++;print $0} END{print "[end] user count is: " count}' /etc/passwd
+
+[start] user count is: 0
+root:x:0:0:root:/root:/bin/bash
+bin:x:1:1:bin:/bin:/sbin/nologin
+daemon:x:2:2:daemon:/sbin:/sbin/nologin
+adm:x:3:4:adm:/var/adm:/sbin/nologin
+lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
+sync:x:5:0:sync:/sbin:/bin/sync
+shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
+halt:x:7:0:halt:/sbin:/sbin/halt
+mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
+operator:x:11:0:operator:/root:/sbin/nologin
+games:x:12:100:games:/usr/games:/sbin/nologin
+ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
+nobody:x:99:99:Nobody:/:/sbin/nologin
+systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
+dbus:x:81:81:System message bus:/:/sbin/nologin
+polkitd:x:999:998:User for polkitd:/:/sbin/nologin
+sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
+postfix:x:89:89::/var/spool/postfix:/sbin/nologin
+chrony:x:998:996::/var/lib/chrony:/sbin/nologin
+[end] user count is: 19
+```
+
+在BEGIN中先定义一个初始的变量count=0,并且打印一段话,然后第二个{}中是具体执行的语句。最后在END中定义结束的操作,打印count的值.....
+
+```bash
+awk 'BEGIN {一开始执行的内容,只执行一遍}{反复执行的内容} END{最后执行的内容,仅一遍}' /etc/passwd
+```
+
+### 6.4.2 实例二:统计某个文件夹下的文件占用的字节数
+
+```bash
+[root@localhost ~]# ll | awk 'BEGIN {size=0} {size=size+$5} END{print "size is ",size}'
+size is 2226
+[root@localhost ~]# ll | awk 'BEGIN {size=0} {size=size+$5} END{print "size is ",size/1024/1024,"M"}'
+size is 0.00212288 M
+```
+
+## 6.5 awk运算符
+
+| 运算符 | 描述 |
+| -------------------------- | -------------------------------- |
+| **赋值运算符** | |
+| = += -= \*= /= %= ^= \*\*= | 赋值语句 |
+| **逻辑运算符** | |
+| ¦¦ | 逻辑或 |
+| && | 逻辑与 |
+| **正则运算符** | |
+| ~ !~ | 匹配正则表达式和不匹配正则表达式 |
+| **关系运算符** | |
+| < <= > >= != == | 关系运算符 |
+| **算数运算符** | |
+| + - | 加,减 |
+| \* / & | 乘,除与求余 |
+| + - ! | 一元加,减和逻辑非 |
+| ^ \*\*\* | 求幂 |
+| ++ -- | 增加或减少,作为前缀或后缀 |
+| **其他运算符** | |
+| $ | 字段引用 |
+| 空格 | 字符串链接符 |
+| ?: | 三目运算符 |
+| ln | 数组中是否存在某键值 |
+
+### 6.5.1 案例
+
+1. awk 赋值运算符:a+=5;等价于: a=a+5;其他同类
+
+```bash
+[root@localhost ~]# awk 'BEGIN{a=5;a+=5;print a}'
+10
+```
+
+2. awk逻辑运算符:判断表达式 a>2&&b>1为真还是为假,后面的表达式同理
+
+```bash
+[root@localhost ~]# awk 'BEGIN{a=1;b=2;print (a>2 && b>1,a=1 || b>1)}'
+0 1
+```
+
+3. awk正则运算符:
+
+```bash
+[root@localhost ~]# awk 'BEGIN{a="100testaa";if(a~/100/) {print "OK"}else {print "NO"}}'
+OK
+```
+
+4. 关系运算符:
+
+ 如: > < 可以作为字符串比较,也可以用作数值比较,关键看操作数如果是字符串就会转换为字符串比较。两个都为数字 才转为数值比较。字符串比较:按照ascii码顺序比较。
+
+```bash
+# 如果是字符的话,就会按照ASCII码的顺序进行比较
+[root@localhost ~]# awk 'BEGIN{a=11;if(a>=9){print"OK"}}'
+OK
+[root@localhost ~]# awk 'BEGIN{a;if(a>=b){print"OK"}}'
+OK
+```
+
+5. 算术运算符:
+
+ 说明:所有用作算术运算符进行操作,操作数自动转为数值,所有非数值都变为0
+
+```bash
+[root@localhost ~]# awk 'BEGIN{a="b";print a++,++a}'
+0 2
+[root@localhost ~]# awk 'BEGIN{a="20b4";print a++,++a}'
+20 22
+```
+
+这里的a++ , ++a与其他语言一样:a++是先赋值加++;++a是先++再赋值
+
+6. 三目运算符`?`
+
+```bash
+[root@localhost ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
+ok
+[root@localhost ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
+err
+```
+
+## 6.6 常用 awk 内置变量
+
+| 变量名 | 属性 |
+| ------ | ----------------------------------- |
+| $0 | 当前记录 |
+| \$1~$n | 当前记录的第n个字段 |
+| FS | 输入字段分割符 默认是空格 |
+| RS | 输入记录分割符 默认为换行符 |
+| NF | 当前记录中的字段个数,就是有多少列 |
+| NR | 已经读出的记录数,就是行号,从1开始 |
+| OFS | 输出字段分割符 默认也是空格 |
+| ORS | 输出的记录分割符 默认为换行符 |
+
+注:内置变量很多,参阅相关资料
+
+1. 字段分隔符 FS FS="\t+" 一个或多个 Tab 分隔
+
+
+```bash
+[root@localhost ~]# cat testfile
+aa bb cc
+[root@localhost ~]# awk 'BEGIN{FS="\t+"}{print $1,$2,$3}' testfile
+aa bb cc
+```
+
+2. FS="[[:space:]+]" 一个或多个空白空格,默认的,匹配到不符合的就停止
+
+```bash
+[root@localhost ~]# cat testfile
+aa bb cc
+[root@localhost ~]# awk 'BEGIN{FS="[[:space:]+]"}{print $1,$2,$3}' testfile
+aa bb
+[root@localhost ~]# awk -F [[:space:]+] '{print $1,$2}' testfile
+aa bb
+```
+
+3. FS="[" "]+" 以一个或多个空格分隔
+
+```bash
+[root@localhost ~]# cat testfile
+aa bb cc
+[root@localhost ~]# awk -F [" "]+ '{print $1,$2,$3}' testfile
+aa bb cc
+```
+
+4. 字段数量 NF:显示满足用:分割,并且有8个字段的
+
+```bash
+[root@localhost ~]# cat testfile
+bin:x:1:1:bin:/bin:/sbin/nologin:888
+bin:x:1:1:bin:/bin:/sbin/nologin
+[root@localhost ~]# awk -F ":" 'NF==8{print $0}' testfile
+bin:x:1:1:bin:/bin:/sbin/nologin:888
+```
+
+5. 记录数量 NR (行号)
+
+```bash
+[root@localhost ~]# ifconfig ens33 | awk -F [" "]+ 'NR==2{print $3}'
+192.168.88.10
+```
+
+6. RS 记录分隔符变量
+
+
+```bash
+# 写法一(命令行)
+[root@localhost ~]# awk 'BEGIN{FS=":";RS="\n"}{ print $1","$2","$3}' testfile
+bin,x,1
+bin,x,1
+
+# 写法二(awk脚本)
+[root@localhost ~]# cat awk.txt
+#!/bin/awk
+BEGIN {
+ FS=":"
+ RS="\n"
+}
+{
+ print $1","$2","$3
+}
+[root@localhost ~]# awk -f awk.txt testfile
+bin,x,1
+bin,x,1
+```
+
+7. OFS:输出字段分隔符
+
+```bash
+[root@localhost ~]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2,$3}' testfile
+bin#x#1
+bin#x#1
+```
+
+8. ORS:输出记录分隔符
+
+```bash
+[root@localhost ~]# awk 'BEGIN{FS=":";ORS="\n\n"}{print $1,$2,$3}' testfile
+bin x 1
+
+bin x 1
+```
+
+## 6.7 awk正则
+
+
+
+| 元字符 | 功能 | 示例 | 解释 |
+| :-------------: | :---------------------------------------------- | ------------------------------------ | ------------------------------------------------------------ |
+| ^ | 首航定位符 | /^root/ | 匹配所有以root开头的行 |
+| $ | 行尾定位符 | /root$/ | 匹配所有以root结尾的行 |
+| . | 匹配任意单个字符 | /r..t/ | 匹配字母r,然后两个任意字符,再以t结尾的行 |
+| * | 匹配0个或多个前导字符(包括回车) | /a*ool/ | 匹配0个或多个a之后紧跟着ool的行,比如ool,aaaaool等 |
+| + | 匹配1个或多个前导字符 | /a+b/ | ab, aaab |
+| ? | 匹配0个或1个前导字符 | /a?b/ | b,ab |
+| [] | 匹配指定字符组内的任意一个字符 | /^[abc]/ | 匹配以a或b或c开头的行 |
+| \[^\] | 匹配不在指定字符组内任意一个字符 | /\^[\^abc]/ | 匹配不以字母a或b或c开头的行 |
+| () | 子表达式组合 | /(rool)+/ | 表示一个或多个rool组合,当有一些字符需要组合时,使用括号括起来 |
+| ¦ | 或者的意思 | /(root)\¦B/ | 匹配root或者B的行 |
+| \ | 转义字符 | /a\/\// | 匹配a// |
+| \~,!\~ | 匹配,不匹配的条件语句 | $1~/root/ | 匹配第一个字段包含字符root的所有记录 |
+| x{m}x{m,}x{m,n} | x重复m次x重复至少m次x重复至少m次,但是不超过n次 | /(root){3}//(root){3,}//(root){3,6}/ | |
+
+awk使用正则表达式
+
+1. 规则表达式
+
+ `awk '/REG/{action} ' file` ,其中/REG/为正则表达式,可以将满足条件的记录送入到:action 进行处理
+
+```bash
+[root@localhost ~]# awk '/root/{print$0}' /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+operator:x:11:0:operator:/root:/sbin/nologin
+[root@localhost ~]# awk -F ":" '$5~/root/{print$0}' /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+[root@localhost ~]# ifconfig ens33 | awk 'BEGIN{FS="[[:space:]:]+"} NR==2{print$3}'
+192.168.88.10
+```
+
+2. 布尔表达式
+
+ `awk '布尔表达式{action}' file` 仅当对前面的布尔表达式求值为真时, awk 才执行代码块
+
+```bash
+[root@localhost ~]# awk -F: '$1=="root"{print$0}' /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+[root@localhost ~]# awk -F: '($1=="root")&&($5=="root"){print$0}' /etc/passwd
+root:x:0:0:root:/root:/bin/bash
+```
+
+## 6.8 awk的if、循环、和数组
+
+### 6.8.1 if 条件判断
+
+awk 提供了非常好的类似于 C 语言的 if 语句
+
+```bash
+{
+ if ($1=="foo"){
+ if ($2=="foo"){
+ print"uno"
+ }else{
+ print"one"
+ }
+ }elseif($1=="bar"){
+ print "two"
+ }else{
+ print"three"
+ }
+}
+```
+
+还可以转换为:
+
+```bash
+{
+ if ( $0 !~ /matchme/ ) {
+ print $1 $3 $4
+ }
+}
+```
+
+### 6.8.2 while 循环
+
+awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。 awk 还有"do...while"循环,它在代码块结尾处对条件求值,而不像标准 while 循环那样在开始处求值。
+
+它类似于其它语言中的"repeat...until"循环。以下是一个示例:
+
+do...while 示例:
+
+```bash
+{
+ count=1 do {
+ print "I get printed at least once no matter what"
+ } while ( count !=1 )
+}
+```
+
+与一般的 while 循环不同,由于在代码块之后对条件求值, "do...while"循环永远都至少执行一次。换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环
+
+### 6.8.3 for 循环
+
+awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环:
+
+```bash
+for ( initial assignment; comparison; increment ) {
+ code block
+}
+```
+
+以下是一个简短示例:
+
+```bash
+[root@localhost ~]# cat awk.txt
+#!/bin/awk
+BEGIN{for ( x=1; x<=4; x++ ) {
+ print "iteration", x
+}}
+[root@localhost ~]# awk -f awk.txt
+iteration 1
+iteration 2
+iteration 3
+iteration 4
+```
+
+**break 和 continue**
+
+如同 C 语言一样, awk 提供了 break 和 continue 语句。使用这些语句可以更好地控制 awk 的循环结构。
+
+**break语句:**
+
+```bash
+[root@localhost ~]# cat awk.txt
+#!/bin/awk
+BEGIN{
+x=1
+while(1) {
+ print "iteration",x
+ if ( x==10 ){
+ break
+ }
+ x++
+}
+}
+[root@localhost ~]# awk -f awk.txt
+iteration 1
+iteration 2
+iteration 3
+iteration 4
+iteration 5
+iteration 6
+iteration 7
+iteration 8
+iteration 9
+iteration 10
+```
+
+**continue 语句:**
+
+```bash
+[root@localhost ~]# cat awk.txt
+#!/bin/awk
+BEGIN{
+x=1
+while (1) {
+ if ( x==4 ) {
+ x++
+ continue
+ }
+ print "iteration", x
+ if ( x>20 ) {
+ break
+ }
+ x++
+}
+}
+[root@localhost ~]# awk -f awk.txt
+iteration 1
+iteration 2
+iteration 3
+iteration 5
+iteration 6
+iteration 7
+iteration 8
+iteration 9
+iteration 10
+iteration 11
+iteration 12
+iteration 13
+iteration 14
+iteration 15
+iteration 16
+iteration 17
+iteration 18
+iteration 19
+iteration 20
+iteration 21
+```
+
+### 6.8.4 数组
+
+AWK 中的数组都是关联数组,数字索引也会转变为字符串索引
+
+在awk中,数组叫关联数组,与我们在其它编程语言中的数组有很大的区别。关联数组,简单来说,类似于python语言中的dict、java语言中的map,其下标不再局限于数值型,而可以是字符串,即下标为key,value=array[key]。既然为key,那其下标也不再是有序的啦。
+
+```shell
+#!/bin/awk
+BEGIN{
+ cities[1]="beijing"
+ cities[2]="shanghai"
+ cities["three"]="guangzhou"
+ for( c in cities) {
+ print cities[c]
+ }
+ print cities[1]
+ print cities["1"]
+ print cities["three"]
+}
+
+awk -f awk.txt
+
+- Linux 的 Shell 种类众多,常见的有:
+
+ - Bourne Shell(/usr/bin/sh或/bin/sh)
+ - Bourne Again Shell(/bin/bash)
+ - C Shell(/usr/bin/csh)
+ - K Shell(/usr/bin/ksh)
+ - Shell for Root(/sbin/sh)
+- 程序编程风格
+
+ - 过程式:以指令为中心,数据服务于命令
+ - 对象式:以数据为中心,命令服务于数据
+ - shell是一种过程式编程
+- 过程式编程
+
+ - 顺序执行
+ - 循环执行
+ - 选择执行
+- 编程语言分类
+
+ - 编译型语言
+ - 解释型语言(shell是一种解释型语言)
+
+
+
+- 运行脚本
+
+ - 给予执行权限,通过具体的文件路径指定文件执行
+ - 直接运行解释器,将脚本作为解释器程序的参数运行
+- bash退出状态码
+- 范围是0-255
+ - 脚本中一旦遇到exit命令,脚本会立即终止,终止退出状态取决于exit命令后面的数字
+ - 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态
+
+# 3. 变量
+
+## 3.1 变量命名
+
+- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
+- 中间不能有空格,可以使用下划线(_)。
+- 不能使用标点符号。
+- 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。
+
+## 3.2 声明变量
+
+访问变量的语法形式为:`${var}` 和 `$var` 。
+
+变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,所以推荐加花括号。
+
+```bash
+#!/bin/bash
+word="hello"
+echo ${word}
+# Output: hello
+```
+
+## 3.3 只读变量
+
+使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
+
+```
+#!/bin/bash
+rword="hello"
+echo ${rword}
+readonly rword
+# rword="bye" # 如果放开注释,执行时会报错
+```
+
+## 3.4 删除变量
+
+```bash
+dword="hello" # 声明变量
+echo ${dword} # 输出变量值
+# Output: hello
+
+unset dword # 删除变量
+echo ${dword}
+# Output: (空)
+```
+
+## 3.5 变量类型
+
+- **局部变量** - 局部变量是仅在某个脚本内部有效的变量。它们不能被其他的程序和脚本访问。
+- **环境变量** - 环境变量是对当前 shell 会话内所有的程序或脚本都可见的变量。创建它们跟创建局部变量类似,但使用的是 `export` 关键字,shell 脚本也可以定义环境变量。
+
+**常见的环境变量:**
+
+| 变量 | 描述 |
+| --------- | -------------------------------------------------- |
+| `$HOME` | 当前用户的用户目录 |
+| `$PATH` | 用分号分隔的目录列表,shell 会到这些目录中查找命令 |
+| `$PWD` | 当前工作目录 |
+| `$RANDOM` | 0 到 32767 之间的整数 |
+| `$UID` | 数值类型,当前用户的用户 ID |
+| `$PS1` | 主要系统输入提示符 |
+| `$PS2` | 次要系统输入提示符 |
+
+- **本地变量** - 生效范围仅为当前shell进程;(其他shell,当前的子sehll进程均无效)
+
+ - 变量赋值:name = “value”
+
+- **位置变量** - shell 脚本中用来引用命令行参数的特殊变量。当你运行一个 shell 脚本时,可以在命令行上传递参数,这些参数可以在脚本中使用位置变量引用。
+
+ 位置变量包括以下几种:
+
+ 1. `$0`: 表示脚本本身的名称。
+ 2. `$1`, `$2`, `$3`, ..., `$n`: 分别表示第1个、第2个、第3个...第n个参数。
+ 3. `$#`: 表示传递给脚本的参数个数。
+ 4. `$*`: 表示所有参数,将所有参数当作一个整体。
+ 5. `$@`: 表示所有参数,但是每个参数都是独立的。
+
+```bash
+[root@localhost ~]# cat hello.sh
+#!/bin/bash
+echo "Script name: $0"
+echo "First argument: $1"
+echo "Second argument: $2"
+echo "Total arguments: $#"
+echo "All arguments: $*"
+echo "All arguments (separately): $@"
+
+[root@localhost ~]# ./hello.sh world 2023
+```
+
+案例:统计给出指定文件的行数
+
+```bash
+[root@localhost ~]# cat hello.sh
+#!/bin/bash
+linecount="$(wc -l /etc/passwd | awk -F" " '{print $1}')"
+echo "This file have ${linecount} lines"
+
+[root@localhost ~]# bash hello.sh
+This file have 21 lines
+```
+
+# 4. 字符串
+
+shell 字符串可以用单引号 `' '`,也可以用双引号 `" "`,也可以不用引号。
+
+- 单引号的特点
+ - 单引号里不识别变量
+ - 单引号里不能出现单独的单引号(使用转义符也不行),但可成对出现,作为字符串拼接使用。
+- 双引号的特点
+ - 双引号里识别变量
+ - 双引号里可以出现转义字符
+
+综上,推荐使用双引号。
+
+## 4.1 字符串的拼接
+
+```bash
+# 使用单引号拼接
+name1='white'
+str1='hello, '${name1}''
+str2='hello, ${name1}'
+echo ${str1}_${str2}
+# Output:
+# hello, white_hello, ${name1}
+
+# 使用双引号拼接
+name2="black"
+str3="hello, "${name2}""
+str4="hello, ${name2}"
+echo ${str3}_${str4}
+# Output:
+# hello, black_hello, black
+```
+
+## 4.2 获取字符串的长度
+
+```bash
+text="12345"
+echo ${#text}
+
+# Output:
+# 5
+```
+
+## 4.3 截取子字符串
+
+`${variable:start:length}`
+
+```bash
+text="12345"
+echo ${text:2:2}
+
+# Output:
+# 34
+```
+
+# 5. 数组
+
+bash 只支持一维数组。
+
+数组下标从 0 开始,下标可以是整数或算术表达式,其值应大于或等于 0。
+
+## 5.1 创建/访问数组
+
+```bash
+array_name=(value1 value2 value3 ...)
+array_name=([0]=value1 [1]=value2 ...)
+
+# 案例一
+[root@localhost ~]# cat a.sh
+#!/bin/bash
+# 创建数组
+fruits=("apple" "banana" "orange")
+
+# 访问元素
+echo "First fruit: ${fruits[0]}"
+echo "All fruits: ${fruits[@]}"
+
+[root@localhost ~]# bash a.sh
+First fruit: apple
+All fruits: apple banana orange
+
+# 案例二
+[root@localhost ~]# cat a.sh
+nums=([0]="nls" [1]="18" [2]="teacher")
+echo ${nums[1]}
+
+[root@localhost ~]# bash a.sh
+18
+```
+
+访问数组中所有的元素:
+
+```bash
+[root@localhost ~]# cat a.sh
+nums=([0]="nls" [1]="18" [2]="teacher")
+echo ${nums[*]}
+echo ${nums[@]}
+
+[root@localhost ~]# bash a.sh
+nls 18 teacher
+nls 18 teacher
+```
+
+## 5.2 获取数组的长度
+
+```bash
+[root@localhost ~]# cat a.sh
+nums=([0]="nls" [1]="18" [2]="teacher")
+echo "数组元素个数为: ${#nums[*]}"
+
+[root@localhost ~]# bash a.sh
+数组元素个数为: 3
+```
+
+## 5.3 删除元素
+
+用`unset`命令来从数组中删除一个元素:
+
+```bash
+[root@localhost ~]# cat a.sh
+nums=([0]="nls" [1]="18" [2]="teacher")
+echo "数组元素个数为: ${#nums[*]}"
+unset nums[0]
+echo "数组元素个数为: ${#nums[*]}"
+
+[root@localhost ~]# bash a.sh
+数组元素个数为: 3
+数组元素个数为: 2
+```
+
+# 6. 运算符
+
+## 6.1 算数运算符
+
+下表列出了常用的算术运算符,假定变量 x 为 10,变量 y 为 20:
+
+| 运算符 | 说明 | 举例 |
+| ------ | --------------------------------------------- | ------------------------------ |
+| + | 加法 | `expr $x + $y` 结果为 30。 |
+| - | 减法 | `expr $x - $y` 结果为 -10。 |
+| * | 乘法 | `expr $x * $y` 结果为 200。 |
+| / | 除法 | `expr $y / $x` 结果为 2。 |
+| % | 取余 | `expr $y % $x` 结果为 0。 |
+| = | 赋值 | `x=$y` 将把变量 y 的值赋给 x。 |
+| == | 相等。用于比较两个数字,相同则返回 true。 | `[ $x == $y ]` 返回 false。 |
+| != | 不相等。用于比较两个数字,不相同则返回 true。 | `[ $x != $y ]` 返回 true。 |
+
+**注意:**条件表达式要放在方括号之间,并且要有空格,例如: `[$x==$y]` 是错误的,必须写成 `[ $x == $y ]`
+
+**示例:**
+
+- expr本身是一个命令,可以直接进行运算
+
+```bash
+x=10
+y=20
+
+echo "x=${x}, y=${y}"
+
+val=`expr ${x} + ${y}`
+echo "${x} + ${y} = $val"
+
+val=`expr ${x} - ${y}`
+echo "${x} - ${y} = $val"
+
+val=`expr ${x} \* ${y}`
+echo "${x} * ${y} = $val"
+
+val=`expr ${y} / ${x}`
+echo "${y} / ${x} = $val"
+
+val=`expr ${y} % ${x}`
+echo "${y} % ${x} = $val"
+
+if [[ ${x} == ${y} ]]
+then
+ echo "${x} = ${y}"
+fi
+if [[ ${x} != ${y} ]]
+then
+ echo "${x} != ${y}"
+fi
+
+# Execute: ./operator-demo.sh
+# Output:
+# x=10, y=20
+# 10 + 20 = 30
+# 10 - 20 = -10
+# 10 * 20 = 200
+# 20 / 10 = 2
+# 20 % 10 = 0
+# 10 != 20
+```
+
+### 6.1.1 案例一:计算ID之和
+
+计算/etc/passwd文件中第10个用户和第15个用户的ID之和
+
+```bash
+[root@localhost ~]# cat id.sh
+#!/bin/bash
+# userid1=$(cat /etc/passwd | sed -n '10p'| awk -F: '{print $3}')
+# userid2=$(cat /etc/passwd | sed -n '15p'| awk -F: '{print $3}')
+userid1=$(awk -F: '{if (NR==10) print $3}' /etc/passwd)
+userid2=$(awk -F: '{if (NR==15) print $3}' /etc/passwd)
+
+userid_sum=$[$userid1 + $userid2]
+echo $userid_sum
+
+# Execute:
+[root@localhost ~]# bash id.sh
+92
+```
+
+### 6.1.2 案例二:统计文件数量
+
+统计/etc/,/var/,/usr/目录下有多少目录和文件
+
+```bash
+[root@localhost ~]# cat file.sh
+#!/bin/bash
+sum_etc=$(find /etc | wc -l)
+sum_var=$(find /var | wc -l)
+sum_usr=$(find /usr | wc -l)
+
+sum=$[$sum_etc + $sum_var + $sum_usr]
+echo $sum
+
+# Execute:
+[root@localhost ~]# bash file.sh
+35686
+```
+
+## 6.2 关系运算符
+
+关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
+
+下表列出了常用的关系运算符,假定变量 x 为 10,变量 y 为 20:
+
+| 运算符 | 说明 | 举例 |
+| ------ | ----------------------------------------------------- | ---------------------------- |
+| `-eq` | 检测两个数是否相等,相等返回 true。 | `[ $a -eq $b ]`返回 false。 |
+| `-ne` | 检测两个数是否相等,不相等返回 true。 | `[ $a -ne $b ]` 返回 true。 |
+| `-gt` | 检测左边的数是否大于右边的,如果是,则返回 true。 | `[ $a -gt $b ]` 返回 false。 |
+| `-lt` | 检测左边的数是否小于右边的,如果是,则返回 true。 | `[ $a -lt $b ]` 返回 true。 |
+| `-ge` | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | `[ $a -ge $b ]` 返回 false。 |
+| `-le` | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | `[ $a -le $b ]`返回 true。 |
+
+**示例:**
+
+```bash
+x=10
+y=20
+
+echo "x=${x}, y=${y}"
+
+if [[ ${x} -eq ${y} ]]; then
+ echo "${x} -eq ${y} : x 等于 y"
+else
+ echo "${x} -eq ${y}: x 不等于 y"
+fi
+
+if [[ ${x} -ne ${y} ]]; then
+ echo "${x} -ne ${y}: x 不等于 y"
+else
+ echo "${x} -ne ${y}: x 等于 y"
+fi
+
+if [[ ${x} -gt ${y} ]]; then
+ echo "${x} -gt ${y}: x 大于 y"
+else
+ echo "${x} -gt ${y}: x 不大于 y"
+fi
+
+if [[ ${x} -lt ${y} ]]; then
+ echo "${x} -lt ${y}: x 小于 y"
+else
+ echo "${x} -lt ${y}: x 不小于 y"
+fi
+
+if [[ ${x} -ge ${y} ]]; then
+ echo "${x} -ge ${y}: x 大于或等于 y"
+else
+ echo "${x} -ge ${y}: x 小于 y"
+fi
+
+if [[ ${x} -le ${y} ]]; then
+ echo "${x} -le ${y}: x 小于或等于 y"
+else
+ echo "${x} -le ${y}: x 大于 y"
+fi
+
+# Execute: ./operator-demo2.sh
+# Output:
+# x=10, y=20
+# 10 -eq 20: x 不等于 y
+# 10 -ne 20: x 不等于 y
+# 10 -gt 20: x 不大于 y
+# 10 -lt 20: x 小于 y
+# 10 -ge 20: x 小于 y
+# 10 -le 20: x 小于或等于 y
+```
+
+### 6.2.1 案例:猜数字小游戏
+
+```bash
+[root@localhost ~]# vim guess.sh
+#!/bin/bash
+num2=66
+while true
+do
+ read -p "请输入你要猜的数字:" num1
+ if [ $num1 -gt $num2 ];then
+ echo "你猜大了"
+ elif [ $num1 -lt $num2 ];then
+ echo "你猜小了"
+ else
+ echo "你猜对了"
+ break
+ fi
+done
+
+# Execute:
+[root@localhost ~]# bash guess.sh
+请输入你要猜的数字:60
+你猜小了
+请输入你要猜的数字:66
+你猜对了
+```
+
+## 6.3 字符串运算符
+
+下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
+
+| 运算符 | 说明 | 举例 |
+| ------ | ------------------------------------------ | -------------------------- |
+| `=` | 检测两个字符串是否相等,相等返回 true。 | `[ $a = $b ]` 返回 false。 |
+| `!=` | 检测两个字符串是否相等,不相等返回 true。 | `[ $a != $b ]` 返回 true。 |
+| `-z` | 检测字符串长度是否为 0,为 0 返回 true。 | `[ -z $a ]` 返回 false。 |
+| `-n` | 检测字符串长度是否为 0,不为 0 返回 true。 | `[ -n $a ]` 返回 true。 |
+| `str` | 检测字符串是否为空,不为空返回 true。 | `[ $a ]` 返回 true。 |
+
+示例:
+
+```bash
+x="abc"
+y="xyz"
+
+
+echo "x=${x}, y=${y}"
+
+if [[ ${x} = ${y} ]]; then
+ echo "${x} = ${y} : x 等于 y"
+else
+ echo "${x} = ${y}: x 不等于 y"
+fi
+
+if [[ ${x} != ${y} ]]; then
+ echo "${x} != ${y} : x 不等于 y"
+else
+ echo "${x} != ${y}: x 等于 y"
+fi
+
+if [[ -z ${x} ]]; then
+ echo "-z ${x} : 字符串长度为 0"
+else
+ echo "-z ${x} : 字符串长度不为 0"
+fi
+
+if [[ -n "${x}" ]]; then
+ echo "-n ${x} : 字符串长度不为 0"
+else
+ echo "-n ${x} : 字符串长度为 0"
+fi
+
+if [[ ${x} ]]; then
+ echo "${x} : 字符串不为空"
+else
+ echo "${x} : 字符串为空"
+fi
+
+# Execute: ./operator-demo5.sh
+# Output:
+# x=abc, y=xyz
+# abc = xyz: x 不等于 y
+# abc != xyz : x 不等于 y
+# -z abc : 字符串长度不为 0
+# -n abc : 字符串长度不为 0
+# abc : 字符串不为空
+```
+
+## 6.4 逻辑运算符
+
+以下介绍 Shell 的逻辑运算符,假定变量 x 为 10,变量 y 为 20:
+
+| 运算符 | 说明 | 举例 |
+| ------ | ---------- | ----------------------------------------------- |
+| `&&` | 逻辑的 AND | `[[ ${x} -lt 100 && ${y} -gt 100 ]]` 返回 false |
+| `||` | 逻辑的 OR | `[[ ${x} -lt 100 && ${y} -gt 100 ]]`返回 true |
+
+示例:
+
+```bash
+x=10
+y=20
+
+echo "x=${x}, y=${y}"
+
+if [[ ${x} -lt 100 && ${y} -gt 100 ]]
+then
+ echo "${x} -lt 100 && ${y} -gt 100 返回 true"
+else
+ echo "${x} -lt 100 && ${y} -gt 100 返回 false"
+fi
+
+if [[ ${x} -lt 100 || ${y} -gt 100 ]]
+then
+ echo "${x} -lt 100 || ${y} -gt 100 返回 true"
+else
+ echo "${x} -lt 100 || ${y} -gt 100 返回 false"
+fi
+
+# Execute: ./operator-demo4.sh
+# Output:
+# x=10, y=20
+# 10 -lt 100 && 20 -gt 100 返回 false
+# 10 -lt 100 || 20 -gt 100 返回 true
+```
+
+## 6.5 布尔运算符
+
+下表列出了常用的布尔运算符,假定变量 x 为 10,变量 y 为 20:
+
+| 运算符 | 说明 | 举例 |
+| ------ | --------------------------------------------------- | ------------------------------------------ |
+| `!` | 非运算,表达式为 true 则返回 false,否则返回 true。 | `[ ! false ]` 返回 true。 |
+| `-o` | 或运算,有一个表达式为 true 则返回 true。 | `[ $a -lt 20 -o $b -gt 100 ]` 返回 true。 |
+| `-a` | 与运算,两个表达式都为 true 才返回 true。 | `[ $a -lt 20 -a $b -gt 100 ]` 返回 false。 |
+
+示例:
+
+```bash
+x=10
+y=20
+
+echo "x=${x}, y=${y}"
+
+if [[ ${x} != ${y} ]]; then
+ echo "${x} != ${y} : x 不等于 y"
+else
+ echo "${x} != ${y}: x 等于 y"
+fi
+
+if [[ ${x} -lt 100 && ${y} -gt 15 ]]; then
+ echo "${x} 小于 100 且 ${y} 大于 15 : 返回 true"
+else
+ echo "${x} 小于 100 且 ${y} 大于 15 : 返回 false"
+fi
+
+if [[ ${x} -lt 100 || ${y} -gt 100 ]]; then
+ echo "${x} 小于 100 或 ${y} 大于 100 : 返回 true"
+else
+ echo "${x} 小于 100 或 ${y} 大于 100 : 返回 false"
+fi
+
+if [[ ${x} -lt 5 || ${y} -gt 100 ]]; then
+ echo "${x} 小于 5 或 ${y} 大于 100 : 返回 true"
+else
+ echo "${x} 小于 5 或 ${y} 大于 100 : 返回 false"
+fi
+
+# Execute: ./operator-demo3.sh
+# Output:
+# x=10, y=20
+# 10 != 20 : x 不等于 y
+# 10 小于 100 且 20 大于 15 : 返回 true
+# 10 小于 100 或 20 大于 100 : 返回 true
+# 10 小于 5 或 20 大于 100 : 返回 false
+```
+
+## 6.6 文件测试运算符
+
+文件测试运算符用于检测 Unix 文件的各种属性。
+
+属性检测描述如下:
+
+| 操作符 | 说明 | 举例 |
+| ------- | ------------------------------------------------------------ | --------------------------- |
+| -b file | 检测文件是否是块设备文件,如果是,则返回 true。 | `[ -b $file ]` 返回 false。 |
+| -c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | `[ -c $file ]` 返回 false。 |
+| -d file | 检测文件是否是目录,如果是,则返回 true。 | `[ -d $file ]` 返回 false。 |
+| -f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | `[ -f $file ]` 返回 true。 |
+| -g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | `[ -g $file ]` 返回 false。 |
+| -k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | `[ -k $file ]`返回 false。 |
+| -p file | 检测文件是否是有名管道,如果是,则返回 true。 | `[ -p $file ]` 返回 false。 |
+| -u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | `[ -u $file ]` 返回 false。 |
+| -r file | 检测文件是否可读,如果是,则返回 true。 | `[ -r $file ]` 返回 true。 |
+| -w file | 检测文件是否可写,如果是,则返回 true。 | `[ -w $file ]` 返回 true。 |
+| -x file | 检测文件是否可执行,如果是,则返回 true。 | `[ -x $file ]` 返回 true。 |
+| -s file | 检测文件是否为空(文件大小是否大于 0),不为空返回 true。 | `[ -s $file ]` 返回 true。 |
+| -e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | `[ -e $file ]` 返回 true。 |
+
+**⌨️ 『示例源码』** [operator-demo6.sh](https://github.com/dunwu/os-tutorial/blob/master/codes/shell/demos/operator/operator-demo6.sh)
+
+```bash
+file="/etc/hosts"
+
+if [[ -r ${file} ]]; then
+ echo "${file} 文件可读"
+else
+ echo "${file} 文件不可读"
+fi
+if [[ -w ${file} ]]; then
+ echo "${file} 文件可写"
+else
+ echo "${file} 文件不可写"
+fi
+if [[ -x ${file} ]]; then
+ echo "${file} 文件可执行"
+else
+ echo "${file} 文件不可执行"
+fi
+if [[ -f ${file} ]]; then
+ echo "${file} 文件为普通文件"
+else
+ echo "${file} 文件为特殊文件"
+fi
+if [[ -d ${file} ]]; then
+ echo "${file} 文件是个目录"
+else
+ echo "${file} 文件不是个目录"
+fi
+if [[ -s ${file} ]]; then
+ echo "${file} 文件不为空"
+else
+ echo "${file} 文件为空"
+fi
+if [[ -e ${file} ]]; then
+ echo "${file} 文件存在"
+else
+ echo "${file} 文件不存在"
+fi
+
+# Execute: ./operator-demo6.sh
+# Output:(根据文件的实际情况,输出结果可能不同)
+# /etc/hosts 文件可读
+# /etc/hosts 文件可写
+# /etc/hosts 文件不可执行
+# /etc/hosts 文件为普通文件
+# /etc/hosts 文件不是个目录
+# /etc/hosts 文件不为空
+# /etc/hosts 文件存在
+```
+
+# 7. 用户交互read
+
+## 7.1 常用选项
+
+| 选项 | 描述 |
+| :--- | :------------------------- |
+| `-p` | 在读取输入之前显示提示信息 |
+| `-n` | 限制输入的字符数 |
+| `-s` | 隐藏用户输入 |
+| `-a` | 将输入存储到数组变量中 |
+| `-d` | 指定用于终止输入的分隔符 |
+| `-t` | 设置超时时间(以秒为单位) |
+| `-e` | 允许使用 Readline 编辑键 |
+| `-i` | 设置默认值 |
+
+示例:
+
+```bash
+#!/bin/bash
+read -p "input you name:" name
+echo $name
+
+# Output:
+nls
+```
+
+## 7.2 案例:计算器
+
+```bash
+#!/bin/bash
+
+echo "Enter the first number:"
+read num1
+echo "Enter the second number:"
+read num2
+
+echo "The sum is: $((num1 + num2))"
+echo "The difference is: $((num1 - num2))"
+echo "The product is: $((num1 * num2))"
+echo "The quotient is: $((num1 / num2))"
+
+# Output:
+[root@localhost ~]# bash read.sh
+Enter the first number:
+10
+Enter the second number:
+10
+The sum is: 20
+The difference is: 0
+The product is: 100
+The quotient is: 1
+```
+
+# 8. 控制语句
+
+## 8.1 条件语句
+
+跟其它程序设计语言一样,Bash 中的条件语句让我们可以决定一个操作是否被执行。结果取决于一个包在`[[ ]]`里的表达式。
+
+由`[[ ]]`(`sh`中是`[ ]`)包起来的表达式被称作 **检测命令** 或 **基元**。这些表达式帮助我们检测一个条件的结果
+
+1. `if` 语句
+
+`if`在使用上跟其它语言相同。如果中括号里的表达式为真,那么`then`和`fi`之间的代码会被执行。`fi`标志着条件代码块的结束。
+
+```bash
+# 写成一行
+if [[ 1 -eq 1 ]]; then echo "1 -eq 1 result is: true"; fi
+# Output: 1 -eq 1 result is: true
+
+# 写成多行
+if [[ "abc" -eq "abc" ]]
+then
+ echo ""abc" -eq "abc" result is: true"
+fi
+# Output: abc -eq abc result is: true
+```
+
+2. `if else` 语句
+
+同样,我们可以使用`if..else`语句,例如:
+
+```bash
+if [[ 2 -ne 1 ]]; then
+ echo "true"
+else
+ echo "false"
+fi
+# Output: true
+```
+
+2. `if elif else` 语句
+
+有些时候,`if..else`不能满足我们的要求。别忘了`if..elif..else`,使用起来也很方便。
+
+```bash
+x=10
+y=20
+if [[ ${x} > ${y} ]]; then
+ echo "${x} > ${y}"
+elif [[ ${x} < ${y} ]]; then
+ echo "${x} < ${y}"
+else
+ echo "${x} = ${y}"
+fi
+# Output: 10 < 20
+```
+
+## 8.2 循环语句
+
+循环其实不足为奇。跟其它程序设计语言一样,bash 中的循环也是只要控制条件为真就一直迭代执行的代码块。Bash 中有四种循环:`for`,`while`,`until`和`select`。
+
+### 8.2.1 for循环
+
+`for`与 C 语言中非常像。看起来是这样:
+
+```bash
+for arg in elem1 elem2 ... elemN
+do
+ ### 语句
+done
+```
+
+在每次循环的过程中,`arg`依次被赋值为从`elem1`到`elemN`。这些值还可以是通配符或者[大括号扩展](https://github.com/denysdovhan/bash-handbook/blob/master/translations/zh-CN/README.md#大括号扩展)。
+
+当然,我们还可以把`for`循环写在一行,但这要求`do`之前要有一个分号,就像下面这样:
+
+```bash
+for i in {1..5}; do echo $i; done
+```
+
+还有,如果你觉得`for..in..do`对你来说有点奇怪,那么你也可以像 C 语言那样使用`for`,比如:
+
+```bash
+for (( i = 0; i < 10; i++ )); do
+ echo $i
+done
+```
+
+当我们想对一个目录下的所有文件做同样的操作时,`for`就很方便了。举个例子,如果我们想把所有的`.bash`文件移动到`script`文件夹中,并给它们可执行权限,我们的脚本可以这样写:
+
+```bash
+DIR=/home/zp
+for FILE in ${DIR}/*.sh; do
+ mv "$FILE" "${DIR}/scripts"
+done
+# 将 /home/zp 目录下所有 sh 文件拷贝到 /home/zp/scripts
+```
+
+#### 8.2.1.1 案例一:创建用户
+
+创建用户user1‐user10家目录,并且在user1‐10家目录下创建1.txt‐10.txt
+
+```bash
+[root@localhost ~]# cat adduser.sh
+#!/bin/bash
+for i in {1..10}
+do
+ mkdir /home/user$i
+ for j in $(seq 10)
+ do
+ touch /home/user$i/$j.txt
+ done
+done
+
+# Output:
+[root@localhost ~]# bash adduser.sh
+[root@localhost ~]# ls /home/
+user01 user10 user3 user5 user7 user9
+user1 user2 user4 user6 user8
+[root@localhost ~]# ls /home/user1
+10.txt 2.txt 4.txt 6.txt 8.txt
+1.txt 3.txt 5.txt 7.txt 9.txt
+```
+
+#### 8.2.1.2 案例二:检查磁盘占用
+
+列出/var/目录下各个子目录占用磁盘大小
+
+```bash
+[root@localhost ~]# cat size.sh
+#!/bin/bash
+for i in `ls /var/`
+do
+ path="/var/$i"
+ if [ -d $path ];then
+ du -sh $path
+ fi
+done
+
+# Output:
+[root@localhost ~]# bash size.sh
+0 /var/adm
+654M /var/cache
+0 /var/crash
+8.0K /var/db
+0 /var/empty
+0 /var/games
+0 /var/gopher
+0 /var/kerberos
+54M /var/lib
+0 /var/local
+0 /var/lock
+3.2M /var/log
+0 /var/mail
+0 /var/nis
+0 /var/opt
+0 /var/preserve
+0 /var/run
+16K /var/spool
+0 /var/tmp
+0 /var/www
+0 /var/yp
+```
+
+#### 8.2.1.3 案例三:测试连通性
+
+批量测试地址是否在线
+
+```bash
+[root@localhost ~]# cat ping.sh
+#!/bin/bash
+for i in {1..10}
+do
+ ping -c 2 192.168.88.$i &> /dev/null
+ if [ $? -eq 0 ];then
+ echo 192.168.88.$i >> /root/host.txt
+ fi
+done
+
+# Output:
+[root@localhost ~]# cat host.txt
+192.168.88.1
+192.168.88.2
+192.168.88.10
+```
+
+### 8.2.2 while循环
+
+`while`循环检测一个条件,只要这个条件为 *真*,就执行一段命令。被检测的条件跟`if..then`中使用的[基元](https://github.com/denysdovhan/bash-handbook/blob/master/translations/zh-CN/README.md#基元和组合表达式)并无二异。因此一个`while`循环看起来会是这样:
+
+```bash
+while 循环条件
+do
+ ### 语句
+done
+```
+
+#### 8.2.2.1 案例一:数字累加
+
+计算1+2+..10的总和
+
+```bash
+[root@localhost ~]# cat sum.sh
+#!/bin/bash
+i=1
+sum=0
+while [ $i -lt 10 ]
+do
+ let sum+=$i
+ let i++
+done
+echo $sum
+
+# Output:
+[root@localhost ~]# bash sum.sh
+45
+```
+
+#### 8.2.2.2 案例二:猜数字小游戏
+
+加上随机数
+
+```bash
+[root@localhost ~]# cat guess.sh
+#!/bin/bash
+num2=$((RANDOM%100+1))
+while true
+do
+ read -p "请输入你要猜的数字:" num1
+ if [ $num1 -gt $num2 ];then
+ echo "你猜大了"
+ elif [ $num1 -lt $num2 ];then
+ echo "你猜小了"
+ else
+ echo "你猜对了"
+ break
+ fi
+done
+
+# Output:
+[root@localhost ~]# bash guess.sh
+请输入你要猜的数字:50
+你猜小了
+请输入你要猜的数字:70
+你猜小了
+请输入你要猜的数字:90
+你猜大了
+请输入你要猜的数字:80
+你猜大了
+```
+
+### 8.2.3 until循环
+
+`until`循环跟`while`循环正好相反。它跟`while`一样也需要检测一个测试条件,但不同的是,只要该条件为 *假* 就一直执行循环:
+
+```bash
+until 条件测试
+do
+ ##循环体
+done
+```
+
+示例:
+
+```bash
+[root@localhost ~]# cat until.sh
+x=0
+until [ ${x} -ge 5 ]; do
+ echo ${x}
+ x=`expr ${x} + 1`
+done
+
+# Output
+[root@localhost ~]# bash until.sh
+0
+1
+2
+3
+4
+```
+
+### 8.2.4 退出循环
+
+`break` 和 `continue`
+
+如果想提前结束一个循环或跳过某次循环执行,可以使用 shell 的`break`和`continue`语句来实现。它们可以在任何循环中使用。
+
+> `break`语句用来提前结束当前循环。
+>
+> `continue`语句用来跳过某次迭代。
+
+示例:
+
+```bash
+# 查找 10 以内第一个能整除 2 和 3 的正整数
+i=1
+while [[ ${i} -lt 10 ]]; do
+ if [[ $((i % 3)) -eq 0 ]] && [[ $((i % 2)) -eq 0 ]]; then
+ echo ${i}
+ break;
+ fi
+ i=`expr ${i} + 1`
+done
+# Output: 6
+```
+
+示例:
+
+```bash
+# 打印10以内的奇数
+for (( i = 0; i < 10; i ++ )); do
+ if [[ $((i % 2)) -eq 0 ]]; then
+ continue;
+ fi
+ echo ${i}
+done
+# Output:
+# 1
+# 3
+# 5
+# 7
+# 9
+```
+
+# 9. 函数
+
+## 9.1 函数定义
+
+bash 函数定义语法如下:
+
+```bash
+[ function ] funname [()] {
+ action;
+ [return int;]
+}
+```
+
+```bash
+function FUNNAME(){
+函数体
+返回值
+}
+FUNNME #调用函数
+```
+
+> 💡 说明:
+>
+> 1. 函数定义时,`function` 关键字可有可无。
+> 2. 函数返回值 - return 返回函数返回值,返回值类型只能为整数(0-255)。如果不加 return 语句,shell 默认将以最后一条命令的运行结果,作为函数返回值。
+> 3. 函数返回值在调用该函数后通过 `$?` 来获得。
+> 4. 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至 shell 解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
+
+示例:
+
+```bash
+[root@localhost ~]# cat func.sh
+#!/bin/bash
+func(){
+ echo "这是我的第一个函数"
+}
+
+echo "------函数执行之前-------"
+func
+echo "------函数执行之前-------"
+
+# Output:
+[root@localhost ~]# bash func.sh
+------函数执行之前-------
+这是我的第一个函数
+------函数执行之前-------
+```
+
+## 9.2 返回值
+
+示例:
+
+```bash
+func(){
+ echo "这个函数会对输入的两个数字进行相加运算..."
+ echo "输入第一个数字: "
+ read aNum
+ echo "输入第二个数字: "
+ read anotherNum
+ echo "两个数字分别为 $aNum 和 $anotherNum !"
+ return $(($aNum+$anotherNum))
+}
+func
+echo "输入的两个数字之和为 $? !"
+#可以使用$?来获取返回值
+```
+
+## 9.3 函数参数
+
+**位置参数**是在调用一个函数并传给它参数时创建的变量
+
+| 变量 | 描述 |
+| -------------- | ------------------------------ |
+| `$0` | 脚本名称 |
+| `$1 … $9` | 第 1 个到第 9 个参数列表 |
+| `${10} … ${N}` | 第 10 个到 N 个参数列表 |
+| `$*` or `$@` | 除了`$0`外的所有位置参数 |
+| `$#` | 不包括`$0`在内的位置参数的个数 |
+| `$FUNCNAME` | 函数名称(仅在函数内部有值) |
+
+示例:
+
+```bash
+#!/bin/bash
+
+x=0
+if [[ -n $1 ]]; then
+ echo "第一个参数为:$1"
+ x=$1
+else
+ echo "第一个参数为空"
+fi
+
+y=0
+if [[ -n $2 ]]; then
+ echo "第二个参数为:$2"
+ y=$2
+else
+ echo "第二个参数为空"
+fi
+
+paramsFunction(){
+ echo "函数第一个入参:$1"
+ echo "函数第二个入参:$2"
+}
+paramsFunction ${x} ${y}
+```
+
+执行结果:
+
+```bash
+[root@localhost ~]# vim func1.sh
+[root@localhost ~]# bash func1.sh
+第一个参数为空
+第二个参数为空
+函数第一个入参:0
+函数第二个入参:0
+[root@localhost ~]# bash func1.sh 10 20
+第一个参数为:10
+第二个参数为:20
+函数第一个入参:10
+函数第二个入参:20
+```
+
+## 9.4 函数处理参数
+
+另外,还有几个特殊字符用来处理参数:
+
+| 参数处理 | 说明 |
+| -------- | ------------------------------------------------ |
+| `$#` | 返回参数个数 |
+| `$*` | 返回所有参数 |
+| `$ | 参数处理 |
+| -------- | ------------------------------------------------ |
+
+| `$!` | 后台运行的最后一个进程的 ID 号 |
+| `$@` | 返回所有参数 |
+| `$-` | 返回 Shell 使用的当前选项,与 set 命令功能相同。 |
+| `$?` | 函数返回值 |
+
+```bash
+runner() {
+ return 0
+}
+
+name=zp
+paramsFunction(){
+ echo "函数第一个入参:$1"
+ echo "函数第二个入参:$2"
+ echo "传递到脚本的参数个数:$#"
+ echo "所有参数:"
+ printf "+ %s\n" "$*"
+ echo "脚本运行的当前进程 ID 号:$$"
+ echo "后台运行的最后一个进程的 ID 号:$!"
+ echo "所有参数:"
+ printf "+ %s\n" "$@"
+ echo "Shell 使用的当前选项:$-"
+ runner
+ echo "runner 函数的返回值:$?"
+}
+paramsFunction 1 "abc" "hello, \"zp\""
+# Output:
+# 函数第一个入参:1
+# 函数第二个入参:abc
+# 传递到脚本的参数个数:3
+# 所有参数:
+# + 1 abc hello, "zp"
+# 脚本运行的当前进程 ID 号:26400
+# 后台运行的最后一个进程的 ID 号:
+# 所有参数:
+# + 1
+# + abc
+# + hello, "zp"
+# Shell 使用的当前选项:hB
+# runner 函数的返回值:0
+```
+
+# 10. 实际案例
+
+## 10.1 案例一:开机显示系统信息脚本
+
+```bash
+[root@localhost ~]# cat os.sh
+#!/bin/bash
+yum install -y net-tools &> /dev/null
+wangka=`ip a | grep ens | head -1 | cut -d: -f2`
+System=$(hostnamectl | grep System | awk '{print $3,$4,$5}')
+Kernel=$(hostnamectl | grep Kernel | awk -F: '{print $2}')
+Virtualization=$(hostnamectl | grep Virtualization| awk '{print $2}')
+Statichostname=$(hostnamectl | grep Static|awk -F: '{print $2}')
+Ens32=$(ifconfig $wangka | awk 'NR==2 {print $2}')
+Lo=$(ifconfig lo0 | awk 'NR==2 {print $2}')
+NetworkIp=$(curl -s icanhazip.com)
+echo "当前系统版本是:$System"
+echo "当前系统内核是:$Kernel"
+echo "当前虚拟平台是:$Virtualization"
+echo "当前主机名是:$Statichostname"
+echo "当前网卡$wangka的地址是:$Ens32"
+echo "当前lo0接口的地址是:$Lo"
+echo "当前公网地址是:$NetworkIp"
+
+# Output:
+[root@localhost ~]# bash os.sh
+当前系统版本是:CentOS Linux 7
+当前系统内核是: Linux 3.10.0-957.el7.x86_64
+当前虚拟平台是:vmware
+当前主机名是: localhost
+当前网卡 ens33的地址是:192.168.88.10
+当前lo0接口的地址是:127.0.0.1
+当前公网地址是:153.101.189.87
+
+```
+
+## 10.2 案例二:监控httpd进程
+
+**需求:**
+
+1.每隔10s监控httpd的进程数,若进程数大于等于500,则自动重启Apache服务,并检测服务是否重启成功
+
+2.若未成功则需要再次启动,若重启5次依旧没有成功,则向管理员发送告警邮件(使用echo输出已发送即可),并退出检测
+
+3.如果启动成功,则等待1分钟后再次检测httpd进程数,若进程数正常,则恢复正常检测(10s一次),否则放弃重启并向管理员发送告警邮件,并退出检测
+
+```bash
+[root@localhost ~]# cat httpd.sh
+#!/bin/bash
+function check_httpd_process_number() {
+process_num=`ps -ef | grep httpd| wc -l`
+
+if [ $process_num -gt 50 ];then
+ systemctl restart httpd &> /dev/null
+ # 重启五次httpd确保服务启动
+ systemctl status httpd &> /dev/null
+ if [ $? -ne 0 ];then
+ num_restart_httpd=0
+ while true;do
+ let num_restart_httpd++
+ systemctl restart httpd &> /dev/null
+ systemctl status httpd &> /dev/null
+ [ $? -eq 0 ] && break
+ [ $num_restart_httpd -eq 6 ] && break
+ done
+ fi
+
+ # 判断重启服务的结果
+ systemctl status httpd &> /dev/null
+ [ $? -ne 0 ] && echo "apache未正常重启,已发送邮件给管理员" && return 1
+ sleep 60
+ return 0
+
+ # 再次判断进程是否正常
+ process_num=`ps -ef | grep httpd| wc -l`
+ if [ $process_num -gt 50 ] ;then
+ echo "apache经过重启进程数依然大于50"
+ return 1
+ else
+ return 0
+ fi
+
+else
+ echo "进程数小于50"
+ sleep 3
+ return 0
+fi
+}
+
+# 每十秒钟执行一次函数,检查进程是否正常
+while true;do
+check_httpd_process_number
+[ $? -eq 1 ] && exit
+done
+
+# Output:
+[root@localhost ~]# bash http.sh
+进程数小于50
+进程数小于50
+进程数小于50
+进程数小于50
+
+# 复制窗口进行压力测试
+[root@localhost ~]# for i in {1..10}; do ab -c $((10000/$i)) -n 2000 http://127.0.0.1/ & done
+```
+
+## 10.3 案例三:统计文件
+
+统计两个目录下的相同文件,以及不同文件
+
+```bash
+#!/bin/bash
+# server1的文件在/test/目录中,server2的文件在/root/demo中,通过md5值来判断文件一致性,最终输出相同文件以及各自的不同文件
+#定义两个数组的索引
+point1=0
+point2=0
+echo "/test/的文件:"
+# 将server1上的文件的散列值记录到数组当中
+for i in `ls /root/demo`;do
+ md5=`md5sum /root/demo/$i | awk '{print $1}'`
+ arrar1[$point1]=$md5:$i
+ echo ${arrar1[$point1]}
+ let point1++
+done
+echo "/root/demo的文件:"
+# 将server2上的文件的散列值记录到数组当中
+for i in `ls /test`;do
+ md5=`md5sum /test/$i | awk '{print $1}'`
+ arrar2[$point2]=$md5:$i
+ echo ${arrar2[$point2]}
+ let point2++
+done
+
+# 找出相同文件以及server1上的独立文件,server1的每个文件都和server2上进行比较
+echo "-------------------------------"
+for i in ${arrar1[@]};do
+ for j in ${arrar2[@]};do
+ temp_flag=0 #定义一个标志位,表示没找到相同的文件
+ server1_md5=`echo $i | awk -F: '{print $1}'`
+ server2_md5=`echo $j | awk -F: '{print $1}'`
+ server1_filename=`echo $i | awk -F: '{print $2}'`
+ server2_filename=`echo $j | awk -F: '{print $2}'`
+ if [ $server1_md5 == $server2_md5 ];then
+ echo -e "两边共同文件\t\t\t$server1_filename"
+ temp_flag=1 #找到了相同的文件
+ break
+ fi
+ done
+ if [ $temp_flag -eq 0 ];then
+ echo -e "server1不同文件\t\t\t$i"
+ fi
+done
+
+# 找出server2上的独立文件
+for i in ${arrar2[@]};do
+ for j in ${arrar1[@]};do
+ temp_flag=0
+ server1_md5=`echo $i | awk -F: '{print $1}'`
+ server2_md5=`echo $j | awk -F: '{print $1}'`
+ server1_filename=`echo $i | awk -F: '{print $2}'`
+ server2_filename=`echo $j | awk -F: '{print $2}'`
+ if [ $server1_md5 == $server2_md5 ];then
+ temp_flag=1
+ break
+ fi
+ done
+ if [ $temp_flag -eq 0 ];then
+ echo -e "server2不同文件\t\t\t$i"
+ fi
+done
+
+```
+
+## 10.4 练习:基于文件的用户登录注册功能
+
+用户名和密码保存在文件中,格式为username:password
\ No newline at end of file
diff --git a/04.自动化运维/02.Shell脚本/1603244500462-e952ebe4-1ece-41cf-aa88-4feb0825ec43.png b/04.自动化运维/02.Shell脚本/1603244500462-e952ebe4-1ece-41cf-aa88-4feb0825ec43.png
new file mode 100644
index 0000000..60ec9bc
Binary files /dev/null and b/04.自动化运维/02.Shell脚本/1603244500462-e952ebe4-1ece-41cf-aa88-4feb0825ec43.png differ
diff --git a/04.自动化运维/02.Shell脚本/u=3041729381,733868634&fm=26&gp=0.jpg b/04.自动化运维/02.Shell脚本/u=3041729381,733868634&fm=26&gp=0.jpg
new file mode 100644
index 0000000..9a9e932
Binary files /dev/null and b/04.自动化运维/02.Shell脚本/u=3041729381,733868634&fm=26&gp=0.jpg differ
diff --git a/04.自动化运维/03.Ansible.md b/04.自动化运维/03.Ansible.md
new file mode 100644
index 0000000..29ff0bb
--- /dev/null
+++ b/04.自动化运维/03.Ansible.md
@@ -0,0 +1,1368 @@
+# 1. ansible自动化运维
+
+## 1.1 ansible介绍
+
+ansible 是一个开源的自动化运维工具,主要用于系统配置管理、应用部署、任务编排等场景。它使用 YAML 语法编写配置文件,语法简单易懂,学习曲线平缓。ansible 的任务是幂等的,意味着多次执行结果是一致的,不会产生意外结果,非常适合于持续部署和集成。
+
+ansible 支持众多常见操作系统和中间件,具有良好的扩展性。同时它还支持自定义模块,可以满足各种复杂的自动化需求。另一个特点是 ansible 不需要在远程主机上安装任何代理,只需要有 SSH 访问权限即可,并且不需要中央控制节点,使用 SSH 协议直接连接远程主机,部署和维护相对简单。ansible 使用 SSH 进行远程连接和命令执行,保证了数据传输的安全性。
+
+ansible由python开发,集合了众多自动化运维工具的优点,实现了批量系统部署、批量程序部署,批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力,真正具有批量部署能力的是ansible运行的模块,ansible只是提供一个框架。
+
+## 1.2 核心组件
+
+
+
+ansible:ansible核心程序。 HostInventory:记录由ansible管理的主机信息,包括端口、密码、ip等。 Playbooks:“剧本”YAML格式文件,多个任务定义在一个文件中,定义主机需要调用哪些模块来完成的功能。 CoreModules:核心模块,主要操作是通过调用核心模块来完成管理任务。 CustomModules:自定义模块,完成核心模块无法完成的功能,支持多种语言。 ConnectionPlugins:连接插件,ansible和Host通信使用
+
+## 1.3 任务执行方式
+
+- ad-HOC 点对点模式 使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令 例如对大量服务器执行shell 或者执行某个linux命令。
+- playbook 模式(剧本模式) 通过编写yaml格式文件组合多个task任务,实现一个想要达到的功能,相对于多个点对点模式组合操作配置,playbook这个功能非常强大
+
+## 1.4 特点
+
+- 不需要在被监控端上安装任何服务程序
+- 无服务器端,使用时直接运行命令即可
+- 基于模块工作,可以使用任意语言开发
+- 使用yaml语言编写playbook
+- 基于ssh工作
+- 可实现多级指挥
+- 具有幂等性,一种操作重复多次执行结果相同
+
+## 1.5 执行过程
+
+- 加载自己的配置文件,默认为/etc/ansible/ansible.cfg
+- 加载自己对应的模块文件
+- 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器
+- 对应执行用户的家目录的.ansible/tmp/xx.py文件
+- 给文件+x执行
+- 执行并将返回结果,删除临时py文件,然后退出
+
+# 2. ansible部署
+
+- 安装ansible
+
+```
+[root@localhost ~]# yum install -y epel-release
+[root@localhost ~]# yum install -y ansible
+```
+
+**说明:**ansible只是一个工具,不需要启动,安装好以后,直接使用即可。并且只有服务端需要安装,客户端不需要安装....
+
+## 2.1 参数说明
+
+```
+`Inventory 文件参数:
+-i 或 --inventory: 指定 Inventory 文件的路径
+-l 或 --limit: 限制操作的主机范围
+-g 或 --groups: 指定要操作的主机组
+`剧本(Playbook)参数:
+-p 或 --playbook-dir: 指定 Playbook 所在目录
+-e 或 --extra-vars: 传递额外的变量
+`任务(Task)参数:
+-m 或 --module-name: 指定要使用的模块名称
+-a 或 --args: 传递模块的参数
+`连接参数:
+-c 或 --connection: 指定连接类型,如 ssh、local 等
+-u 或 --user: 指定远程连接的用户
+`输出参数:
+-v 或 --verbose: 增加输出信息的详细程度
+--check: 进行一次"试运行",不会实际改变任何状态
+--diff: 显示配置文件的改动情况
+`其他参数:
+-f 或 --forks: 指定并行执行的进程数
+-t 或 --tags: 只执行带有指定 tag 的任务
+--list-hosts: 列出受管主机
+--list-tasks: 列出所有任务
+```
+
+## 2.2 快速开始
+
+**实验环境:**四台Linux虚拟机,HOSTNAME分别为:ansible、server1、server2、server3
+
+其中,ansible做为服务端,其他server均作为客户端
+
+1. 免密登录
+
+```
+# 在ansible上修改hosts文件,方便使用主机名管理主机
+[root@ansible ~]# vim /etc/hosts
+.......
+192.168.88.10 server1
+192.168.88.20 server2
+192.168.88.30 server3
+
+
+# 生成密钥对
+[root@ansible ~]# ssh-keygen -P "" -t rsa
+.....
+# 将公钥发送给需要被管理端,以实现免密登录
+
+
+[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@server1
+[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@server2
+[root@ansible ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@server3
+```
+
+### 2.2.1 常用工具
+
+- ansible:临时命令执行工具,常用于执行临时命令
+- ansible-doc:常用于模块功能的查询
+- ansible-playbook:用于执行剧本
+
+### 2.2.2 主要配置文件
+
+- /etc/ansible/ansible.cfg:主配置文件
+- /etc/ansible/hosts:主机清单文件
+- /etc/ansible/roles:角色目录
+
+### 2.2.3 配置主机清单
+
+编辑`/etc/ansible/hosts`文件,再最后面添加上被管理端
+
+```
+[root@ansible ~]# vim /etc/ansible/hosts
+......
+......
+......
+## [dbservers]
+##
+## db01.intranet.mydomain.net
+## db02.intranet.mydomain.net
+## 10.25.1.56
+## 10.25.1.57
+
+
+# Here's another example of host ranges, this time there are no
+# leading 0s:
+
+
+## db-[99:101]-node.example.com
+# 定义自己的主机组
+[all_servers]
+server1
+server2
+server3
+
+
+[node1]
+server1
+
+
+[node2]
+server2
+
+
+[node3]
+server3
+```
+
+- 主配置文件`ansible.cfg`,默认可以不用改
+
+```
+[root@localhost ~]# vim /etc/ansible/ansible.cfg
+[defaults]
+
+
+# some basic default values...
+
+
+#inventory = /etc/ansible/hosts # 定义主机清单文件
+#library = /usr/share/my_modules/ # 库文件的存放位置
+#module_utils = /usr/share/my_module_utils/
+#remote_tmp = ~/.ansible/tmp # 生成的临时py文件在远程主机的目录
+#local_tmp = ~/.ansible/tmp # 生成的临时py文件在本地主机的目录
+#plugin_filters_cfg = /etc/ansible/plugin_filters.yml
+#forks = 5 # 默认的并发数
+#poll_interval = 15 # 默认的线程池
+#sudo_user = root # 默认的sudo用户
+#ask_sudo_pass = True
+#ask_pass = True
+#transport = smart
+#remote_port = 22
+#module_lang = C
+#module_set_locale = False
+transport = smart
+在ansible配置中,transport = smart 是指定 ansible 用于远程连接的传输机制。smart 是 ansible 的默认传输选项,它会尝试根据环境自动选择最佳的传输机制。
+
+
+当 smart 被设置时,ansible 会按照以下顺序尝试不同的传输机制:
+
+
+如果已经建立了 SSH 连接(例如,通过 SSH Agent 或者在 ansible.cfg 中配置了 SSH 连接参数),则使用 SSH 传输。
+如果未建立 SSH 连接,并且目标主机是本地主机,则使用本地传输(即直接在本地执行命令)。
+如果未建立 SSH 连接,并且目标主机是远程主机,则使用 Paramiko 传输(基于 Python 的 SSH2 实现)。
+通过使用 smart 选项,ansible 可以自动选择合适的传输机制,以确保在不同的环境中都能正常工作。如果您希望显式地指定传输机制,可以将 transport 设置为 ssh、local 或 paramiko,以强制使用相应的传输方式。
+```
+
+### 2.2.4 执行状态
+
+ansible的执行状态
+
+- 绿色:执行成功并且不需要做改变的操作
+- 黄色:执行成功并且对目标主机做变更
+- 红色:执行失败
+- 粉色:警告信息
+- 蓝色:显示ansible命令执行的过程
+
+## 2.3 常用模块
+
+### 2.3.1 ping模块
+
+测试与主机的连通性
+
+示例:
+
+```
+[root@ansible ~]# ansible -m ping all_servers
+server1 | SUCCESS => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": false,
+ "ping": "pong"
+}
+server3 | SUCCESS => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": false,
+ "ping": "pong"
+}
+server2 | SUCCESS => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": false,
+ "ping": "pong"
+}
+
+
+# 返回说明:
+"SUCCESS" 表示 ansible 成功执行了任务,没有遇到错误。
+"ansible_facts" 是一个包含 ansible 任务执行期间收集到的事实(facts)的字典。
+"discovered_interpreter_python" 是一个收集到的事实,它指示目标主机上的 Python 解释器的路径为 /usr/bin/python。这对于后续的 ansible 任务可能需要使用 Python 的情况很有用。
+"changed" 表示 ansible 是否对目标主机进行了更改。在这种情况下,值为 false 表示没有进行任何更改。
+"ping" 是一个简单的回应,用于测试与目标主机的连通性。如果值为 "pong",表示与目标主机的连接正常。
+```
+
+### 2.3.2 Group模块
+
+用户创建和修改用户组
+
+示例:对node1主机组的成员创建一个IT组,组ID为111
+
+```
+[root@ansible ~]# ansible-doc -s group
+action: group
+gid # 设置组的GID号
+name= # 管理组的名称
+state # 指定组状态,默认为创建,设置值为absent为删除
+system # 设置值为yes,表示为创建系统组
+
+
+[root@ansible ~]# ansible -m group -a "name=IT gid=111 system=yes" node1
+server1 | CHANGED => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": true,
+ "gid": 111,
+ "name": "IT",
+ "state": "present",
+ "system": true
+}
+```
+
+### 2.3.3 User模块
+
+用于对用户的创建,修改和删除等操作
+
+```
+# 查看某个模块的具体用法
+[root@ansible ~]# ansible-doc -l|wc -l
+3387 #共有3387个模块
+[root@ansible ~]# ansible‐doc ‐s user
+ comment # 用户的描述信息
+ createhom # 是否创建家目录
+ force # 在使用`state=absent'是, 行为与`userdel ‐‐force'一致.
+ group # 指定基本组
+ groups # 指定附加组,如果指定为('groups=')表示删除所有组
+ home # 指定用户家目录
+ name # 指定用户名
+ password # 指定用户密码
+ remove # 在使用 `state=absent'时, 行为是与 `userdel ‐‐remove'一致.
+ shell # 指定默认shell
+ state #设置帐号状态,不指定为创建,指定值为absent表示删除
+ system # 当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
+ uid #指定用户的uid
+ update_password # 更新用户密码
+ expires #指明密码的过期时间
+ ......
+```
+
+示例:在主机组node1上创建一个系统用户张三,家目录为/home/zhangsan,uid为111,附加组为IT,以及给一个注释
+
+```
+[root@ansible ~]# ansible -m user -a "system=yes name=zhangsan home=/home/zhangsan uid=111 groups=IT comment='hello zhangsan'" node1
+server1 | CHANGED => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": true,
+ "comment": "hello zhangsan",
+ "create_home": true,
+ "group": 995,
+ "groups": "IT",
+ "home": "/home/zhangsan",
+ "name": "zhangsan",
+ "shell": "/bin/bash",
+ "state": "present",
+ "system": true,
+ "uid": 111
+}
+
+
+
+
+
+
+# 删除用户及家目录
+[root@ansible ~]# ansible -m user -a "name=zhangsan state=absent remove=yes" node1
+
+
+# 添加系统用户,指定uid、家目录、主组及注释、密码
+[root@ansible ~]# ansible -m user -a "system=yes name=zhangsan home=/home/zhangsan uid=111 group=root comment='hello zhangsan' password='123456' shell=/bin/cbash " node1
+```
+
+### 2.3.4 Command模块
+
+command模块是ansible默认使用的模块。不支持管道,变量及重定向等
+
+示例:
+
+```
+[root@ansible ~]# ansible-doc ‐s command
+......
+......
+[root@ansible ~]# ansible -a "touch /root/ansible.txt" all_servers
+[WARNING]: Consider using the file module with state=touch rather than running
+'touch'. If you need to use command because file is insufficient you can add
+'warn: false' to this command task or set 'command_warnings=False' in
+ansible.cfg to get rid of this message.
+server2 | CHANGED | rc=0 >>
+
+
+server1 | CHANGED | rc=0 >>
+
+
+server3 | CHANGED | rc=0 >>
+
+
+
+
+[root@ansible ~]# ansible -a "find / -name ifcfg-ens33" all_servers
+server1 | CHANGED | rc=0 >>
+/etc/sysconfig/network-scripts/ifcfg-ens33
+server2 | CHANGED | rc=0 >>
+/etc/sysconfig/network-scripts/ifcfg-ens33
+server3 | CHANGED | rc=0 >>
+/etc/sysconfig/network-scripts/ifcfg-ens33
+```
+
+### 2.3.5 Shell模块
+
+在远程主机上执行bash命令
+
+相对于command而言,支持性更好一点,但是对于某些复杂的命令,也可能会执行失败
+
+解决方法:可以把命令卸载脚本中,使用script模块执行脚本到远程主机
+
+```
+[root@ansible ~]# ansible -m shell -a "hostname" all_servers
+server1 | CHANGED | rc=0 >>
+server1
+server2 | CHANGED | rc=0 >>
+server2
+server3 | CHANGED | rc=0 >>
+server3
+```
+
+### 2.3.6 Script模块
+
+可以发送shell脚本到远程主机上并执行
+
+示例:
+
+```
+[root@ansible ~]# vim test.sh
+#!/bin/bash
+for i in `seq 5`
+do
+ touch /root/test_${i}.txt
+done
+
+
+# script模块
+[root@ansible ~]# ansible -m script -a "/root/test.sh" node2
+server2 | CHANGED => {
+ "changed": true,
+ "rc": 0,
+ "stderr": "Shared connection to server2 closed.\r\n",
+ "stderr_lines": [
+ "Shared connection to server2 closed."
+ ],
+ "stdout": "",
+ "stdout_lines": []
+}
+
+
+# server2验证
+[root@server2 ~]# ls
+anaconda-ks.cfg test_1.txt test_3.txt test_5.txt
+ansible.txt test_2.txt test_4.txt
+
+
+# 参数说明
+chdir参数: 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到 chdir 参数指定的目录中。
+creates参数: 使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本
+removes参数: 使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本
+```
+
+### 2.3.7 Copy模块
+
+用于向复制文件到主机组中
+
+参数解释:
+
+```
+[root@ansible ~]# ansible-doc -s copy
+backup:在覆盖之前,将源文件备份,备份文件包含时间信息。
+content:用于替代“src”,可以直接设定指定文件的值
+dest:必选项。要将源文件复制到的远程主机的绝对路径
+directory_mode:递归设定目录的权限,默认为系统默认权限
+force:强制覆盖目的文件内容,默认为yes
+others:所有的file模块里的选项都可以在这里使用
+src:被复制到远程主机的本地文件,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制
+
+
+ansible -m copy -a "src=/本地文件 dest=/远程文件" nodes
+```
+
+示例:
+
+- 在创建文件时修改文件的属主和属组信息
+
+```
+[root@ansible ~]# ansible -m copy -a "src=/root/test.sh dest=/root/test1 owner=zhangsan group=ansibles" node1
+```
+
+- 在传输文件时修改文件的权限信息,并且备份远程主机文件
+
+```
+[root@ansible ~]# ansible -m copy -a "src=/root/test.sh dest=/root/test2 backup=yes mode=777" node1
+```
+
+- 创建一个文件并直接编辑文件
+
+```
+[root@ansible ~]# ansible -m copy -a "content='hello ansibles\n' dest=/root/test3" node1
+```
+
+### 2.3.8 File模块
+
+用于对文件进行相关操作
+
+参数解释:
+
+```
+[root@ansible ~]# ansible‐doc ‐s file
+‐ name: Sets attributes of files
+ force:需要在两种情况下强制创建软链接,一种是源文件不存在,但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
+ group:定义文件/目录的属组
+ mode:定义文件/目录的权限
+ owner:定义文件/目录的属主
+ path:必选项,定义文件/目录的路径
+ recurse:递归设置文件的属性,只对目录有效
+ src:被链接的源文件路径,只应用于state=link的情况
+ dest:被链接到的路径,只应用于state=link的情况
+ state:
+ absent: 删除文件
+ directory:如果目录不存在,就创建目录
+ file:验证文件是否存在,即使文件不存在,也不会被创建
+ link:创建软链接
+ hard:创建硬链接
+ touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其后修改时间
+```
+
+示例:
+
+- 创建目录
+
+```
+[root@ansible ~]# ansible -m file -a "name=test1 owner=root group=root mode=644 state=directory " node1
+```
+
+- 创建文件
+
+```
+[root@ansible ~]# ansible -m file -a "path=/root/test2 owner=root group=root mode=644 state=touch" node1
+```
+
+- 删除文件/目录
+
+```
+[root@ansible ~]# ansible -m file -a "path=/root/test2 state=absent" node1
+```
+
+- 创建软链接文件
+
+```
+[root@ansible ~]# ansible -m file -a "src=/root/test1 dest=/root/test2 state=link" node1
+```
+
+- 创建硬链接文件
+
+```
+[root@ansible ~]# ansible -m file -a "src=/root/test.txt dest=/root/test2 state=hard" node2
+```
+
+### 2.3.9 Yum模块
+
+用于远程操作主机下载软件包
+
+参数说明:
+
+```
+[root@ansible ~]# ansible‐doc ‐s yum
+ conf_file #设定远程yum安装时所依赖的配置文件。如配置文件没有在默认的位置。
+ disable_gpg_check #是否禁止GPG checking,只用于`present' or `latest'。
+ disablerepo #临时禁止使用yum库。 只用于安装或更新时。
+ enablerepo #临时使用的yum库。只用于安装或更新时。
+ name= #所安装的包的名称
+ state #present安装, latest安装最新的, absent 卸载软件。
+ update_cache #强制更新yum的缓存
+```
+
+示例:
+
+```
+[root@ansible ~]# ansible -m yum -a "name=httpd state=latest" node3
+server3 | CHANGED => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": true,
+ "changes": {
+ "installed": [
+ "httpd"
+ ],
+ "updated": []
+ },
+ "msg": "",
+ "rc": 0,
+```
+
+### 2.3.10 Service模块
+
+用于远程管理主机上的service服务类
+
+参数说明:
+
+```
+[root@ansible ~]# ansible-doc -s service
+> SERVICE (/usr/lib/python2.7/site‐packages/ansible/modules/system/service.py)
+ Controls services on remote hosts. Supported init systems include BSD init, OpenRC, SysV, Solaris
+ SMF, systemd, upstart. For Windows targets, use the [win_service] module instead.
+ * note: This module has a corresponding action plugin.
+ ......
+ ......
+ arguments #命令行提供额外的参数
+ enabled #设置开机启动,可以设置为yes或者no。
+ name= #服务名称
+ runlevel #开机启动的级别,一般不用指定。
+ sleep #在重启服务的过程中,是否等待。如在服务关闭以后等待2秒再启动。
+ state #started启动服务, stopped停止服务, restarted重启服务, reloaded重载配置
+```
+
+示例:
+
+```
+[root@ansible ~]# ansible -m service -a "name=httpd state=started" node3
+server3 | CHANGED => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": true,
+ "name": "httpd",
+ "state": "started"
+ .....
+ .....
+```
+
+### 2.3.11 Selinux模块
+
+用于管理远程主机的selinux设置
+
+参考说明:
+
+```
+[root@node1 ~]# ansible-doc -s selinux
+# selinux模块针对selinux的修改操作是针对配置文件进行修改的
+‐ name: Change policy and state of SELinux
+configfile:
+描述: SELinux 配置文件的路径,如果不是标准路径。
+参数类型: 字符串
+policy:
+描述: 要使用的 SELinux 策略的名称。
+参数类型: 字符串
+state:
+描述: (必需) SELinux 的模式。
+参数类型: 字符串
+可选值:
+enforcing: 强制 SELinux 策略生效。
+permissive: 以警告模式运行 SELinux,不会阻止任何操作。
+disabled: 完全禁用 SELinux。
+```
+
+示例:
+
+```
+[root@ansible ~]# ansible -m selinux -a "state=enforcing policy=targeted" node1
+[WARNING]: Reboot is required to set SELinux state to 'enforcing'
+server1 | CHANGED => {
+ "ansible_facts": {
+ "discovered_interpreter_python": "/usr/bin/python"
+ },
+ "changed": true,
+ "configfile": "/etc/selinux/config",
+ "msg": "Config SELinux state changed from 'disabled' to 'enforcing'",
+ "policy": "targeted",
+ "reboot_required": true,
+ "state": "enforcing"
+}
+```
+
+# 3. Playbook(剧本)
+
+## 3.1 介绍
+
+Ansible playbook是一种可执行的YAML文件,用于描述如何部署和配置一个系统或应用程序。一个playbook由一个或多个play组成,每个play都针对特定的主机或主机组执行一系列任务。
+
+一个playbook的基本结构如下:
+
+```
+- hosts: all
+ vars:
+ package_name: nginx
+ config_file: /etc/nginx/nginx.conf
+ tasks:
+ - name: Install Nginx
+ yum:
+ name: "{{ package_name }}"
+ state: present
+ - name: Copy Nginx configuration
+ copy:
+ src: nginx.conf
+ dest: "{{ config_file }}"
+ notify:
+ - restart nginx
+ handlers:
+ - name: restart nginx
+ service:
+ name: nginx
+ state: restarted
+```
+
+在上面的例子中,我们定义了以下几个主要字段:
+
+- `hosts`: 指定要运行任务的主机或主机组。
+- `vars`: 定义要在playbook中使用的变量。
+- `tasks`: 定义要执行的任务列表。每个任务都有一个名称和一个模块。
+- `handlers`: 定义当某些任务触发时需要执行的处理程序,比如重启服务。
+
+执行playbook剧本:
+
+`ansible-playbook xxxxx.yaml`即可
+
+## 3.2 快速开始
+
+### 3.2.1 案例:服务安装
+
+安装nginx并且修改配置文件
+
+1. 先编写一个nginx的子配置文件
+
+```
+[root@ansible ~]# mkdir -p playbook/conf
+[root@ansible ~]# cd playbook/conf
+[root@ansible conf]# cat site.conf
+server {
+ listen 666;
+ server_name localhost;
+
+
+ location / {
+ root /data;
+ index index.html
+ }
+}
+```
+
+1. 编写playbook,要求是为目标机器安装nginx并且拷贝配置文件到该机器上,然后启动nginx。
+
+```
+[root@ansible playbook]# vim nginx.yaml
+- name: install nginx web server
+ hosts: node1
+ remote_user: root
+
+
+ tasks:
+ - name: Install epel-release
+ yum:
+ name: epel-release
+ state: latest
+
+
+ - name: Install Nginx
+ yum:
+ name: nginx
+ state: latest
+
+
+ - name: Copy conf to nginx.conf.d
+ copy:
+ src: /root/playbook/conf/site.conf
+ dest: /etc/nginx/conf.d/site.conf
+
+
+ - name: Create "data" directory
+ file:
+ name: /data
+ state: directory
+
+
+ - name: Start Nginx service
+ service:
+ name: nginx
+ state: started
+
+
+ - name: create web index file
+ shell: echo "Install Nginx use Ansible...." > /data/index.html
+```
+
+
+
+## 3.3 高级配置
+
+### 3.3.1 fact(事实变量)
+
+Ansible 内置了大量的事实(fact)变量,可以在 Playbook 中使用。这些事实变量可以帮助我们更好地了解目标主机的环境和配置信息,从而编写更加智能和动态的自动化脚本。
+
+常用的内置事实变量包括:
+
+1. **操作系统信息**:
+ - `ansible_distribution`: 操作系统发行版名称,如 "CentOS"、"Ubuntu"
+ - `ansible_distribution_version`: 操作系统版本号
+ - `ansible_os_family`: 操作系统家族,如 "RedHat"、"Debian"
+ - `ansible_kernel`: 内核版本
+2. **硬件信息**:
+ - `ansible_processor`: CPU 型号
+ - `ansible_processor_vcpus`: 虚拟 CPU 核数
+ - `ansible_memtotal_mb`: 内存总量(MB)
+ - `ansible_architecture`: CPU 架构,如 "x86_64"
+3. **网络信息**:
+ - `ansible_default_ipv4`: 默认 IPv4 地址和网关
+ - `ansible_all_ipv4_addresses`: 所有 IPv4 地址
+ - `ansible_interfaces`: 所有网络接口名称
+ - `ansible_hostname`: 主机名
+4. **其他信息**:
+ - `ansible_user_id`: 当前执行 Ansible 的用户 ID
+ - `ansible_date_time`: 主机当前日期和时间
+ - `ansible_env`: 主机环境变量
+ - `ansible_play_hosts`: 当前 play 中涉及的所有主机
+
+这些事实变量可以帮助我们编写出更加智能和定制化的 Playbook。比如,我们可以根据操作系统的不同,执行不同的软件包安装任务;根据 CPU 架构,选择合适的软件包版本;根据内存大小,调整应用程序的配置等。
+
+### 3.3.2 循环迭代
+
+在playbook中,可以使用循环进行数据的迭代。这样一个模块就可以执行多次任务,因为往往我们部署一个服务的时候,都需要安装多个软件包的。
+
+示例:使用yum循环安装软件包
+
+```
+- name: Install packages
+ yum:
+ name: "{{ item }}"
+ state: present
+ loop:
+ - nginx
+ - mysql
+ - php
+```
+
+或者:
+
+```
+- name: Install packages
+ yum:
+ name: "{{ item }}"
+ state: present
+ with_items:
+ - httpd
+ - mysql
+ - php
+```
+
+这样就可以实现一个yum安装多个软件包了,避免了playbook过于臃肿。
+
+#### 3.3.2.1 RHCE真题讲解(2023-10)
+
+创建一个名为 /home/student/ansible/packages.yml的 playbook:
+
+1. 将 php 和 mariadb 软件包安装到 dev、test 和 prod 主机组中的主机上
+2. 将 Development Tools 软件包组安装到 dev 主机组中的主机上
+3. 将 dev 主机组中主机上的所有软件包更新为最新版本
+
+```
+[root@ansible ~]# vim playbook/packages.yml
+- name: install pkgs
+ hosts: dev,test,prod
+ tasks:
+ - name: install mariadb php
+ yum:
+ name: "{{ item }}"
+ state: present
+ loop:
+ - php
+ - mariadb
+
+
+- name: install group pkgs
+ hosts: dev
+ tasks:
+ - name: install Development Tools
+ yum:
+ name: "@Development Tools"
+ state: present
+
+
+- name: update pkgs
+ hosts: dev
+ tasks:
+ - name: update pkgs
+ yum:
+ name: "*"
+ state: latest
+
+
+```
+
+#### 3.3.2.2 案例:循环创建用户
+
+循环创建用户,用户信息如下 名称、组、家目录、shell、描述信息 zhangsan xsb /home/xsb/zhangsan /bin/bash 销售 lisi xsb /home/xsb/lisi /bin/bash 销售 wangwu jsb /home/jsb/wangwu /bin/sh java工程师 maliu jsb /home/jsb/maliu /bin/sh linux工程师 zhaoqi cwb /home/cwb/zhaoqi /bin/sh 会计
+
+循环创建出以上用户并指定用户信息:
+
+```
+[root@ansible ~]# vim playbook/user.yml
+- name: Manage user
+ hosts: node1
+ remote_user: root
+ tasks:
+ - name: Ensure groups xsb, jsb, cwb exist
+ group:
+ name: "{{ item.group }}"
+ with_items:
+ - { group: xsb }
+ - { group: jsb }
+ - { group: cwb }
+
+
+ - name: Create users zhangsan, lisi, wangwu, maliu, zhaoqi
+ user:
+ name: "{{ item.name }}"
+ group: "{{ item.group }}"
+ shell: "{{ item.shell }}"
+ comment: "{{ item.comment }}"
+ home: "{{ item.home }}"
+ with_items:
+ - { name: 'zhangsan', group: 'xsb', home: '/home/xsb/zhangsan', shell: '/bin/bash', comment: '销售' }
+ - { name: 'lisi', group: 'xsb', home: '/home/xsb/lisi', shell: '/bin/bash', comment: '销售' }
+ - { name: 'wangwu', group: 'jsb', home: '/home/jsb/wangwu', shell: '/bin/sh', comment: 'java工程师' }
+ - { name: 'maliu', group: 'jsb', home: '/home/jsb/maliu', shell: '/bin/sh', comment: 'linux工程师' }
+ - { name: 'zhaoqi', group: 'cwb', home: '/home/cwb/zhaoqi', shell: '/bin/sh', comment: '会计' }
+
+
+```
+
+
+
+### 3.3.3 条件判断
+
+在 Ansible Playbook 中,我们可以使用条件判断语句来根据不同的条件执行不同的任务。
+
+**when 语句:**
+
+`when` 语句是最常用的条件判断语句。它可以根据变量的值、事实(facts)或者 Jinja2 表达式来决定是否执行某个任务。
+
+```
+- name: Install packages on CentOS 7
+ yum:
+ name:
+ - httpd
+ - mariadb-server
+ state: present
+ when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 7
+
+
+- name: Install packages on CentOS 8
+ yum:
+ name:
+ - nginx
+ - mysql-server
+ state: present
+ when: ansible_distribution == 'CentOS' and ansible_distribution_major_version|int == 8
+```
+
+在这个例子中:
+
+1. 第一个任务会在 CentOS 7 系统上安装 httpd 和 mariadb-server 软件包。`when` 语句确保了只有在 `ansible_distribution` 等于 'CentOS' 且 `ansible_distribution_major_version` 等于 7 时,这个任务才会执行。
+2. 第二个任务会在 CentOS 8 系统上安装 nginx 和 mysql-server 软件包。同样的,`when` 语句确保了只有在 `ansible_distribution` 等于 'CentOS' 且 `ansible_distribution_major_version` 等于 8 时,这个任务才会执行。
+
+#### 3.3.3.1 RHCE真题讲解(2023-10-)
+
+**考试原题(第八题):**
+
+创建一个名为/home/student/ansible/parted.yml 的playbook,它将在dev主机组上运行下列任务
+
+1. 如果磁盘/dev/vdd存在,则创建1500m分区
+2. 如果无法创建请求的分区大小,应显示错误消息 Could not create partition of that size,并且应改为使用大小 800m。
+3. 如果磁盘/dev/vdd不存在 ,应显示错误消息 disk /dev/vdd does not exist。
+4. 如果磁盘/dev/vdb存在,则创建1500m分区
+5. 如果无法创建请求的分区大小,应显示错误消息 Could not create partition of that size,并且应改为使用大小 800m。
+6. 最后分区都要格式化为ext4文件系统,并挂载在/mnt/fs01上
+
+**简化题目:**在所有机器上创建sdb1分区,大小为1Gib,前提是sdb存在,如果不存在,请提示.......
+
+```
+[root@ansible playbook]# vim disk.yaml
+- name: Create sdb1 partition
+ hosts: all_servers
+ tasks:
+ - name: Check if sdb block device exists
+ stat:
+ path: /dev/sdb
+ register: sdb_stat
+
+
+ - name: Create 1GB partition on sdb
+ parted:
+ device: /dev/sdb
+ number: 1
+ state: present
+ part_end: 1GB
+ when: sdb_stat.stat.exists
+
+
+ - name: sdb block device not exists
+ debug:
+ msg: "sdb block device does not exist, cannot create partition."
+ when: not sdb_stat.stat.exists
+
+
+
+
+# Output:
+TASK [Create 1GB partition on sdb] ************************************ *********
+skipping: [server1]
+skipping: [server3]
+changed: [server2]
+
+
+TASK [sdb block device not exists] ************************************ *********
+ok: [server1] => {
+ "msg": "sdb block device does not exist, cannot create partition."
+}
+skipping: [server2]
+ok: [server3] => {
+ "msg": "sdb block device does not exist, cannot create partition."
+}
+```
+
+**验证:**
+
+```
+[root@server2 ~]# lsblk
+NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
+sda 8:0 0 20G 0 disk
+├─sda1 8:1 0 1G 0 part /boot
+└─sda2 8:2 0 19G 0 part
+ ├─centos-root 253:0 0 17G 0 lvm /
+ └─centos-swap 253:1 0 2G 0 lvm [SWAP]
+sdb 8:16 0 2G 0 disk
+└─sdb1 8:17 0 953M 0 part
+sr0 11:0 1 918M 0 rom
+```
+
+## 3.4 Jinjia2模板
+
+Jinja2是一个功能强大的Python模板引擎,它被广泛应用于Ansible的playbook中。Jinja2模板语法提供了丰富的功能,使得在playbook中插入动态内容变得更加容易和灵活。
+
+简单来讲,就是将原本静态的playbook转变为动态的。
+
+### 3.4.1 RHCE真题讲解(2023-10)
+
+**原题(第九题):**生成主机文件
+
+1. 编写模板文件/home/student/ansible/hosts.j2 ,针对每个清单主机包含一行内容,其格式与 /etc/hosts 相同。
+2. 创建名为 /home/student/ansible/hosts.yml 的playbook,它将使用此模板在 dev 主机组中的主 机上生成文件 /etc/myhosts。
+3. 该 playbook 运行后,dev 主机组中主机上的文件/etc/myhosts 应针对每个受管主机包含一行内 容。
+
+**题目变更如下:**
+
+我们使用jinjia2和ansible内置变量动态的生成hosts文件,并且发送给远程主机
+
+1. 编写模板文件
+
+```
+[root@ansible playbook]# vim hosts.j2
+127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
+::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
+
+
+{% for host in groups.all_servers %}
+{{hostvars[host].ansible_ens33.ipv4.address}} {{hostvars[host].ansible_hostname}}
+{% endfor %}
+```
+
+1. 编写hosts.yaml剧本来渲染并且发送该模板文件到目标主机,使之替换原本的hosts
+
+```
+[root@ansible playbook]# vim hosts.yaml
+- name: Config hosts file
+ hosts: all_servers
+ remote_user: root
+
+
+ tasks:
+ - name: copy hosts.j2 to group servers
+ template:
+ src: hosts.j2
+ dest: /etc/hosts
+
+# 执行该playbook
+[root@ansible playbook]# ansible-playbook hosts.yaml
+```
+
+1. 检查并验证:
+
+```
+[root@server1 ~]# cat /etc/hosts
+127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
+::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
+
+
+192.168.88.10 server1
+192.168.88.20 server2
+192.168.88.30 server3
+```
+
+### 3.4.2 案例:生成nginx配置文件
+
+我们可以在playbook中自定义变量,然后更具自定义的变量使用jinjia2模板渲染nginx的配置文件
+
+1. 先编写nginx.yaml剧本,在里面定义变量
+
+```
+[root@ansible ~]# mkdir ansible
+[root@ansible ~]# cd ansible
+[root@ansible ansible]# vim nginx.yaml
+- name: nginx conf
+ hosts: node1
+ remote_user: root
+ vars:
+ nginx_vhosts:
+ - web1:
+ listen: 8080
+ root: "/var/www/nginx/web1/"
+ - web2:
+ listen: 8080
+ server_name: "web2.baidu.com"
+ root: "/var/www/nginx/web2/"
+ - web3:
+ listen: 8080
+ server_name: "web3.baidu.com"
+ root: "/var/www/nginx/web3/"
+ tasks:
+ - name: mkdir /data
+ file:
+ name: /data
+ state: directory
+ - name: template config
+ template:
+ src: /root/ansible/site.conf.j2
+ dest: /data/nginx.conf
+```
+
+1. 编写nginx子配置文件site.conf,子配置文件中使用jinjia2语法进行渲染
+
+```
+[root@ansible ansible]# vim site.conf.j2
+{% for vhost in nginx_vhosts %}
+server {
+ listen {{ vhost.listen }}
+ {% if vhost.server_name is defined %}
+server_name {{ vhost.server_name }}
+ {% endif %}
+root {{ vhost.root }}
+}
+{% endfor %}
+```
+
+1. server1上验证配置文件是否渲染成功
+
+```
+[root@server1 ~]# cat /data/nginx.conf
+server {
+ listen 8080
+ root /var/www/nginx/web1/
+}
+server {
+ listen 8080
+ server_name web2.baidu.com
+ root /var/www/nginx/web2/
+}
+server {
+ listen 8080
+ server_name web3.baidu.com
+ root /var/www/nginx/web3/
+}
+```
+
+# 4. Role(角色)
+
+Ansible 中的 Role 是一种组织和重用代码的强大方式。角色可以帮助你将相关的任务、变量、文件等集中管理,使得代码更加模块化和可重用。
+
+如果将所有的play都写在一个playbook中,很容易导致这个playbook文件变得臃肿庞大,且不易读。因此,可以将多个不同任务分别写在不同的playbook中,然后使用include将其包含进去即可。而role则是整合playbook的方式。无论是include还是role,其目的都是分割大playbook以及复用某些细化的play甚至是task。
+
+## 4.1 目录结构
+
+在角色中,将task,templates,handlers,files等内容都分开存放,然后再playbook中直接调用角色即可.....
+
+```
+[root@ansible roles]# tree apache/
+apache/
+├── defaults
+│ └── main.yml
+├── files
+├── handlers
+│ └── main.yml
+├── meta
+│ └── main.yml
+├── README.md
+├── tasks
+│ └── main.yml
+├── templates
+├── tests
+│ ├── inventory
+│ └── test.yml
+└── vars
+ └── main.yml
+```
+
+- `defaults/main.yml`: 定义角色的默认变量
+- `handlers/main.yml`: 定义角色的处理程序
+- `meta/main.yml`: 定义角色的元数据,如依赖关系、作者信息等
+- `tasks/main.yml`: 定义角色的主要任务
+- `templates/`: 存放角色使用的模板文件
+- `tests/`: 存放角色的测试相关文件
+- `vars/main.yml`: 定义角色的变量
+
+## 4.2 初始化自定义Role
+
+可以使用ansible-galaxy工具通过init选项初始化一个角色
+
+```
+[root@ansible roles]# ansible-galaxy init apache
+- Role apache was created successfully
+[root@ansible role]# ls apache/
+defaults files handlers meta README.md tasks templates tests vars
+```
+
+## 4.3 案例:使用Role安装httpd
+
+1. 初始化httpd角色
+
+```
+[root@ansible roles]# ansible-galaxy init httpd
+- Role httpd was created successfully
+[root@ansible role]# tree httpd/
+httpd/
+├── defaults
+│ └── main.yml
+├── files
+├── handlers
+│ └── main.yml
+├── meta
+│ └── main.yml
+├── README.md
+├── tasks
+│ └── main.yml
+├── templates
+├── tests
+│ ├── inventory
+│ └── test.yml
+└── vars
+ └── main.yml
+
+
+8 directories, 8 files
+```
+
+1. 编写角色中的task
+
+```
+[root@ansible httpd]# vim tasks/main.yml
+# tasks file for httpd
+- name: Install httpd
+ yum:
+ name: httpd
+ state: present
+- name: copy site2.conf to apache web server
+ copy:
+ src: site.conf
+ dest: /etc/httpd/conf.d/site2.conf
+
+
+- name: create directory1 for apache web server
+ file:
+ name: /data/site1/
+ state: directory
+
+
+- name: create directory2 for apache web server
+ file:
+ name: /data/site2/
+ state: directory
+
+
+- name: Start httpd
+ service:
+ name: httpd
+ state: started
+- name: Write index file
+ shell: echo "site1" > /data/site1/index.html && echo "site2" > /data/site2/index.html
+```
+
+1. 编写角色中的file
+
+```
+[root@ansible httpd]# vim files/site.conf
+Listen 8080
+Listen 9090
+
+
+
+
+## 3.6 Zabbix常用术语
+
+- 主机:一台你想监控的网络设备,用IP或域名表示
+- 主机组:主机的逻辑组;它包含主机和模板。一个主机组里的主机和模板之间并没有任何直接的关联。通常在给不同用户组的主机分配权限时候使用主机组。
+- 监控项:你想要接收的主机的特定数据,一个度量数据。
+- 触发器:一个被用于定义问题阈值和“评估”监控项接收到的数据的逻辑表达式 当接收到的数据高于阈值时,触发器从“OK”变成“Problem”状态。当接收到的数据低于阈值时,触发器保留/返回一个“OK”的状态。
+
+# 4. Zabbix-server部署
+
+## 4.1 安装Zabbix 服务端
+
+1. 准备zabbix的yum源,这里通过安装zabbix-release软件包来自动获取zabbix的源。然后安装服务端相关组件
+
+ 官网地址:https://www.zabbix.com/
+
+```bash
+[root@server1 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-latest-6.0.el9.noarch.rpm
+[root@server1 ~]# yum install -y zabbix-server-mysql zabbix-web-mysql zabbix-apache-conf zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
+
+# 安装中文插件
+[root@server1 ~]# yum install -y glibc-langpack-zh.x86_64
+```
+
+2. 关闭防火墙和Selinux
+
+```bash
+[root@server1 ~]# setenforce 0
+[root@server1 ~]# systemctl stop firewalld
+```
+
+## 4.2 准备数据库环境
+
+1. 安装数据库,这里还是选择mariadb即可
+
+```bash
+[root@server1 ~]# yum install -y mariadb-server
+# 启动mariadb数据库
+[root@server1 ~]# systemctl enable --now mariadb
+# 初始化数据库并设置密码
+[root@server1 ~]# mysqladmin -uroot password '123456'
+# 测试数据库连接是否正常
+[root@server1 ~]# mysql -uroot -p123456 -e "show databases;"
++--------------------+
+| Database |
++--------------------+
+| information_schema |
+| mysql |
+| performance_schema |
+| test |
++--------------------+
+```
+
+2. 创建zabbix所需数据库以及zabbix账户
+
+```bash
+[root@localhost ~]# mysql -uroot -p123456
+# 创建zabbix库
+MariaDB [(none)]> create database zabbix character set utf8mb4 collate utf8mb4_bin;
+Query OK, 1 row affected (0.00 sec)
+# 创建zabbix账户
+MariaDB [(none)]> grant all privileges on zabbix.* to zabbix@localhost identified by '123456';
+Query OK, 0 rows affected (0.00 sec)
+# 刷新账户信息
+MariaDB [(none)]> flush privileges;
+Query OK, 0 rows affected (0.00 sec)
+MariaDB [(none)]> set global log_bin_trust_function_creators = 1;
+```
+
+## 4.3 修改服务端相关配置
+
+1. 导入初始架构数据
+
+```bash
+[root@server1 ~]# zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -D zabbix -uzabbix -p123456
+# zabbix安装包中有一个SQL文件,这是zabbix架构的初始数据。
+[root@server1 ~]# mysql -uzabbix -p123456 -D zabbix -e "show tables"
++----------------------------+
+| Tables_in_zabbix |
++----------------------------+
+| acknowledges |
+| actions |
+| alerts |
+| application_discovery |
+| application_prototype |
+| application_template |
+| applications |
+| auditlog |
+| auditlog_details |
+| autoreg_host |
+......
+......
+......
+[root@server1 ~]# mysql -uroot -p123456 -e "set global log_bin_trust_function_creators = 0;"
+```
+
+2. 配置zabbix连接数据库
+
+```bash
+[root@server1 ~]# vim /etc/zabbix/zabbix_server.conf
+DBPassword=123456
+```
+
+3. 启动所有服务
+
+```bash
+# 安装zabbix的时候,会附带安装httpd来提供web服务,因为zabbix默认情况下是有一个web网站的
+[root@server1 ~]# systemctl start zabbix-server zabbix-agent httpd php-fpm
+[root@localhost ~]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
+LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
+LISTEN 0 4096 0.0.0.0:10050 0.0.0.0:*
+LISTEN 0 4096 0.0.0.0:10051 0.0.0.0:*
+LISTEN 0 511 *:80 *:*
+LISTEN 0 128 [::]:22 [::]:*
+LISTEN 0 80 *:3306 *:*
+LISTEN 0 4096 [::]:10050 [::]:*
+LISTEN 0 4096 [::]:10051 [::]:*
+```
+
+## 4.4 服务端初始化
+
+完成上述配置后,可以在浏览器中输入`http://IP/zabbix`打开zabbix的web界面开始初始化
+
+1. 进入初始化页面,可以选择中文
+
+
+
+2. 状态检测
+
+ 确保所有的php检测都是ok的状态
+
+
+
+3. 连接数据库
+
+ 数据库的信息按照图上的填入,其中密码是我们刚刚设置的zabbix用户的密码,端口号3306
+
+
+
+4. zabbix信息
+
+ 填写主机名以及选择正确的时区
+
+
+
+5. 完成安装
+
+ 看到如下界面,说明zabbix初始化成功
+
+
+
+6. 登录zabbix的web网站,默认用户名和密码如下
+
+ **username:**Admin
+
+ **password:**zabbix
+
+
+
+7. 进入Zabbix界面
+
+
+
+## 4.5 客户端配置
+
+1. 在server2上安装zabbix-agent客户端
+
+```bash
+[root@server2 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/6.0/rhel/9/x86_64/zabbix-release-latest-6.0.el9.noarch.rpm
+[root@server2 ~]# yum install zabbix-agent -y
+```
+
+2. 修改客户端配置文件
+
+```bash
+[root@server2 ~]# vim /etc/zabbix/zabbix_agentd.conf
+# 主要修改以下三个参数
+Server=192.168.88.10
+ServerActive=192.168.88.10
+Hostname=server_10
+```
+
+3. 启动zabbix-agent
+
+```bash
+[root@server2 ~]# setenforce 0
+[root@server2 ~]# systemctl stop firewalld
+[root@server2 ~]# systemctl start zabbix-agent.service
+```
+
+# 5. 快速使用
+
+## 5.1 主机监控
+
+先简单的监控一个主机的状态和信息
+
+1. 添加一个主机
+
+
+
+2. 填写主机信息
+
+
+
+3. 添加模板
+
+zabbix内置了很多模板,比如监控Linux主机的模板,监控httpd的模板,监控MySQL的模板等等。我们可以直接使用这些模板,当然也可以自定义。
+
+
+
+4. 查看监控项
+
+在监测中,点击最新数据,然后过滤出server_10主机,就可以看到各个监控项的具体数据
+
+
+
+查看具体数据
+
+
+
+### 5.1.1 手动添加主机监控项
+
+模板中内置的很多的监控项,但是如果没有我们想要的监控项的话,我们可以手动添加。
+
+1. 创建监控项
+
+在配置中,选择对应的主机,然后创建监控项
+
+
+
+2. 创建一个监控项用于查看已挂载文件系统情况
+
+
+
+3. 查看监控项获取到的的监控结果
+
+
+
+## 5.2 自定义应用配置监控项
+
+### 5.2.1 Nginx进程监控
+
+在server2上安装nginx服务,然后编写监控项配置文件,来监控nginx的进程数量
+
+#### 5.2.1.1 安装nginx
+
+```bash
+[root@server2 ~]# yum install -y epel-release nginx
+[root@server2 ~]# systemctl enable --now nginx
+```
+
+#### 5.2.1.2 配置监控项文件
+
+```bash
+[root@server2 ~]# vim /etc/zabbix/zabbix_agentd.d/userparameter_nginx.conf
+UserParameter=nginx_process_num,ps aux | grep -c nginx
+
+# 重启zabbix-agent
+[root@server2 ~]# systemctl restart zabbix-agent
+```
+
+#### 5.2.1.3 服务端验证
+
+可以在服务端上安装一个zabbix工具`zabbix-get`,可以通过该工具在命令行中验证监控项的是否生效
+
+```bash
+[root@server1 ~]# yum install -y zabbix-get
+[root@server1 ~]# zabbix_get -s 192.168.88.20 -k nginx_process_num
+7
+```
+
+#### 5.2.1.4 添加监控项
+
+在web网站上使用刚刚编写的监控项
+
+
+
+查看刚刚添加的监控项键值的状态为已启用
+
+
+
+查看具体的检测到的数据,在菜单栏中点击监测->最新数据,然后过滤刚刚的监控项
+
+
+
+查看数据统计以及变化折线图
+
+
+
+#### 5.2.1.5 添加触发器
+
+给该监控项添加触发器,让他能够出发警告通知
+
+
+
+创建一个新的触发器
+
+
+
+可以看到我们刚刚添加的触发器
+
+
+
+#### 5.2.1.6 手动宕机告警测试
+
+在server2上手动关闭nginx后,在仪表盘中查看告警信息
+
+```bash
+[root@server2 ~]# systemctl stop nginx
+```
+
+查看仪表盘,可以看到告警在闪烁
+
+
+
+可以看到这里有一个告警信息,说明我们刚刚创建的触发器生效了。
+
+这样的话,运维工程师就可以直接在这个网站上看到当前服务器组或者集群中各个机器和服务的状态。 不需要在一个一个登录上去查看了。
+
+但是只是这样还是不够只能,稍后我们将继续配置触发告警以后,通过邮件或者叮叮企业微信等平台向工程师发送告警信息。
+
+## 5.3 常见服务的监控项
+
+### 5.3.1 Redis自定义监控项
+
+```bash
+vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/redis.conf
+UserParameter=Redis.Status,/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 ping |grep -c PONG
+UserParameter=Redis_conn[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "connected_clients" | awk -F':' '{print $2}'
+UserParameter=Redis_rss_mem[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_memory_rss" | awk -F':' '{print $2}'
+UserParameter=Redis_lua_mem[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_memory_lua" | awk -F':' '{print $2}'
+UserParameter=Redis_cpu_sys[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_cpu_sys" | awk -F':' '{print $2}'
+UserParameter=Redis_cpu_user[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_cpu_user" | awk -F':' '{print $2}'
+UserParameter=Redis_cpu_sys_cline[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_cpu_sys_children" | awk -F':' '{print $2}'
+UserParameter=Redis_cpu_user_cline[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "used_cpu_user_children" | awk -F':' '{print $2}'
+UserParameter=Redis_keys_num[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep -w "$$1" | grep -w "keys" | grep db$3 | awk -F'=' '{print $2}' | awk -F',' '{print $1}'
+UserParameter=Redis_loading[*],/usr/local/redis/bin/redis-cli -h $1 -p $2 info | grep loading | awk -F':' '{print $$2}'
+
+Redis.Status --检测Redis运行状态, 返回整数
+Redis_conn --检测Redis成功连接数,返回整数
+Redis_rss_mem --检测Redis系统分配内存,返回整数
+Redis_lua_mem --检测Redis引擎消耗内存,返回整数
+Redis_cpu_sys --检测Redis主程序核心CPU消耗率,返回整数
+Redis_cpu_user --检测Redis主程序用户CPU消耗率,返回整数
+Redis_cpu_sys_cline --检测Redis后台核心CPU消耗率,返回整数
+Redis_cpu_user_cline --检测Redis后台用户CPU消耗率,返回整数
+Redis_keys_num --检测库键值数,返回整数
+Redis_loding --检测Redis持久化文件状态,返回整数
+```
+
+### 5.3.2 Nginx自定义监控项
+
+```bash
+vim /etc/nginx/conf.d/default.conf
+ location /nginx-status
+ {
+ stub_status on;
+ access_log off;
+ allow 127.0.0.1;
+ deny all;
+ }
+
+
+vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/nginx.conf
+UserParameter=Nginx.active,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | awk '/Active/ {print $NF}'
+UserParameter=Nginx.read,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | grep 'Reading' | cut -d" " -f2
+UserParameter=Nginx.wrie,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | grep 'Writing' | cut -d" " -f4
+UserParameter=Nginx.wait,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | grep 'Waiting' | cut -d" " -f6
+UserParameter=Nginx.accepted,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | awk '/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $1}'
+UserParameter=Nginx.handled,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | awk '/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $2}'
+UserParameter=Nginx.requests,/usr/bin/curl -s "http://127.0.0.1:80/nginx-status" | awk '/^[ \t]+[0-9]+[ \t]+[0-9]+[ \t]+[0-9]+/ {print $3}'
+```
+
+### 5.3.3 TCP协议自定义监控项
+
+```bash
+vim /usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh
+#!/bin/bash
+function ESTAB {
+/usr/sbin/ss -ant |awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'ESTAB' | awk '{print $2}'
+}
+function TIMEWAIT {
+/usr/sbin/ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'TIME-WAIT' | awk '{print $2}'
+}
+function LISTEN {
+/usr/sbin/ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'LISTEN' | awk '{print $2}'
+}
+$1
+
+vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/cattcp.conf
+UserParameter=tcp[*],/usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh $1
+
+tcp[TIMEWAIT] --检测TCP的驻留数,返回整数
+tcp[ESTAB] --检测tcp的连接数、返回整数
+tcp[LISTEN] --检测TCP的监听数,返回整数
+```
+
+### 5.3.4 系统监控自带监控项
+
+```bash
+agent.ping 检测客户端可达性、返回nothing表示不可达。1表示可达
+system.cpu.load --检测cpu负载。返回浮点数
+system.cpu.util -- 检测cpu使用率。返回浮点数
+vfs.dev.read -- 检测硬盘读取数据,返回是sps.ops.bps浮点类型,需要定义1024倍
+vfs.dev.write -- 检测硬盘写入数据。返回是sps.ops.bps浮点类型,需要定义1024倍
+net.if.out[br0] --检测网卡流速、流出方向,时间间隔为60S
+net-if-in[br0] --检测网卡流速,流入方向(单位:字节) 时间间隔60S
+proc.num[] 目前系统中的进程总数,时间间隔60s
+proc.num[,,run] 目前正在运行的进程总数,时间间隔60S
+###处理器信息
+通过zabbix_get 获取负载值
+合理的控制用户态、系统态、IO等待时间剋保证进程高效率的运行
+系统态运行时间较高说明进程进行系统调用的次数比较多,一般的程序如果系统态运行时间占用过高就需要优化程序,减少系统调用
+io等待时间过高则表明硬盘的io性能差,如果是读写文件比较频繁、读写效率要求比较高,可以考虑更换硬盘,或者使用多磁盘做raid的方案
+system.cpu.swtiches --cpu的进程上下文切换,单位sps,表示每秒采样次数,api中参数history需指定为3
+system.cpu.intr --cpu中断数量、api中参数history需指定为3
+system.cpu.load[percpu,avg1] --cpu每分钟的负载值,按照核数做平均值(Processor load (1 min average per core)),api中参数history需指定为0
+system.cpu.load[percpu,avg5] --cpu每5分钟的负载值,按照核数做平均值(Processor load (5 min average per core)),api中参数history需指定为0
+system.cpu.load[percpu,avg15] --cpu每5分钟的负载值,按照核数做平均值(Processor load (15 min average per core)),api中参数history需指定为0
+```
+
+### 5.3.5 自定义系统监控项
+
+```bash
+###内存相关
+vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/catcarm.conf
+UserParameter=ram.info[*],/bin/cat /proc/meminfo |awk '/^$1:{print $2}'
+ram.info[Cached] --检测内存的缓存使用量、返回整数,需要定义1024倍
+ram.info[MemFree] --检测内存的空余量,返回整数,需要定义1024倍
+ram.info[Buffers] --检测内存的使用量,返回整数,需要定义1024倍
+
+####TCP相关的自定义项
+vim /usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh
+#!/bin/bash
+function ESTAB {
+/usr/sbin/ss -ant |awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'ESTAB' | awk '{print $2}'
+}
+function TIMEWAIT {
+/usr/sbin/ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'TIME-WAIT' | awk '{print $2}'
+}
+function LISTEN {
+/usr/sbin/ss -ant | awk '{++s[$1]} END {for(k in s) print k,s[k]}' | grep 'LISTEN' | awk '{print $2}'
+}
+$1
+
+vim /usr/local/zabbix/etc/zabbix_agentd.conf.d/cattcp.conf
+UserParameter=tcp[*],/usr/local/zabbix/share/zabbix/alertscripts/tcp_connection.sh $1
+
+tcp[TIMEWAIT] --检测TCP的驻留数,返回整数
+tcp[ESTAB] --检测tcp的连接数、返回整数
+tcp[LISTEN] --检测TCP的监听数,返回整数
+```
+
+# 6. Zabbix告警配置
+
+## 6.1 Zabbix通过邮件告警
+
+### 6.1.1 配置告警设置
+
+1. 配置E-mail参数
+
+ 在菜单栏中选择管理->报警媒介类型
+
+
+
+按照图中配置参数,最后面的密码是在QQ邮箱中申请的**授权码**
+
+
+
+2. 测试是否能够发信
+
+
+
+如果QQ邮箱测试失败的同学,可以尝试网易的163邮箱,亲测可以,需要注册邮箱号,开启smtp服务,配置如下
+
+
+
+3. 修改Admin用户的报警媒介
+
+
+
+4. 配置告警动作
+
+这里定义如果触发告警,应该怎么处理。以及如果发送邮件,邮件的内容是什么样的....
+
+
+
+当然也可以自定义告警信息
+
+
+
+
+
+### 6.1.2 邮件告警测试
+
+手动停止server2上面的nginx服务以后,查看邮件
+
+
+
+可以看到,成功通过邮件发送告警信息
+
+当问题恢复以后,也会发送邮件给我们
+
+
+
+## 6.2 Zabbix通过钉钉告警
+
+### 6.2.1 创建钉钉群聊
+
+先下载电脑版本的钉钉,然后创建一个群聊(创建群聊需要三个好友起步,大家可以相互之间添加好友)并且创建群聊
+
+### 6.2.2 添加群机器人
+
+添加自定义机器人,并且配置关键词
+
+
+
+保存好Webhook,并且设置安全关键词为:告警
+
+
+
+### 6.2.3 创建python脚本
+
+由于zabbix无法直接向钉钉发送告警信息,所以这里需要借助python脚本来实现,让zabbix调用python脚本来向机器人接口发送信息
+
+1. 安装requests模块
+
+```bash
+[root@server1 ~]# yum install -y python-requests
+```
+
+2. python脚本如下:
+
+```bash
+[root@server1 alertscripts]# cd /usr/lib/zabbix/alertscripts
+[root@server1 alertscripts]# vim zabbix_send_ding.py
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Author: 英格无敌牛老师
+import requests
+import json
+import sys
+import os
+
+headers = {'Content-Type': 'application/json;charset=utf-8'}
+api_url = "https://oapi.dingtalk.com/robot/send?access_token=8eab8f6f2d872a0e14376fd782b6aaf40bd57b1352f9cc8ed42c238baaec80e0"
+def msg(text):
+ json_text= {
+ "msgtype": "text",
+ "at": {
+ "atMobiles": [
+ "18888888888"
+ ],
+ "isAtAll": True
+ },
+ "text": {
+ "content": text
+ }
+ }
+ response = requests.post(api_url,json.dumps(json_text),headers=headers).content
+ print(response)
+
+if __name__ == '__main__':
+# 这里用发送关键字用来触发告警
+ text = "告警"
+# 使用sys.argv来接收一个参数,该参数是zabbix发送的消息
+ # text = sys.argv[1]
+ msg(text)
+```
+
+3. 测试脚本
+
+```bash
+# 如果手动测试脚本的话,需要把text = sys.argv[1]先注释了
+[root@server1 alertscripts]# chmod a+x zabbix_send_ding.py
+[root@server1 alertscripts]# ./zabbix_send_ding.py
+{"errcode":0,"errmsg":"ok"}
+```
+
+### 6.2.4 配置zabbix钉钉告警
+
+1. 添加告警媒介
+
+ 因为我们使用的python脚本只接收一个参数(内容),所以只需要添加一个参数{ALERT.MESSAGE}即可
+
+
+
+2. 添加处理动作
+
+
+
+
+
+恢复操作
+
+
+
+告警消息内容如下:
+
+```bash
+【zabbix告警】
+告警问题:{EVENT.NAME}
+告警时间:{EVENT.DATE}-{EVENT.TIME}
+告警主机:{HOST.NAME}
+告 警 IP:{HOST.IP}
+监控项目:{ITEM.NAME}
+故障等级:{EVENT.SEVERITY}
+
+
+【zabbix告警恢复】
+恢复时间:{EVENT.DATE}-{EVENT.TIME}
+告警名称:{EVENT.NAME}
+告警主机:{HOST.NAME}
+告 警 IP:{HOST.IP}
+告警等级:{EVENT.SEVERITY}
+
+
+【zabbix告警更新】
+{USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.
+{EVENT.UPDATE.MESSAGE}
+```
+
+3. 绑定用户,填写钉钉的手机号即可
+
+
+
+### 6.2.5 测试钉钉告警
+
+
+
diff --git a/05.监控告警/01.Zabbix/1604564765251-b49bb305-e64a-4d66-be84-e5326100d97c.png b/05.监控告警/01.Zabbix/1604564765251-b49bb305-e64a-4d66-be84-e5326100d97c.png
new file mode 100644
index 0000000..b49c488
Binary files /dev/null and b/05.监控告警/01.Zabbix/1604564765251-b49bb305-e64a-4d66-be84-e5326100d97c.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811191936758.png b/05.监控告警/01.Zabbix/image-20240811191936758.png
new file mode 100644
index 0000000..6b25103
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811191936758.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811192208427.png b/05.监控告警/01.Zabbix/image-20240811192208427.png
new file mode 100644
index 0000000..7a3a9ae
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811192208427.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811192344941.png b/05.监控告警/01.Zabbix/image-20240811192344941.png
new file mode 100644
index 0000000..1a8da17
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811192344941.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811205608526.png b/05.监控告警/01.Zabbix/image-20240811205608526.png
new file mode 100644
index 0000000..b0de29c
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811205608526.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811205636906.png b/05.监控告警/01.Zabbix/image-20240811205636906.png
new file mode 100644
index 0000000..32aadb0
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811205636906.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811210327296.png b/05.监控告警/01.Zabbix/image-20240811210327296.png
new file mode 100644
index 0000000..2e15dd8
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811210327296.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811210412566.png b/05.监控告警/01.Zabbix/image-20240811210412566.png
new file mode 100644
index 0000000..d05ec5b
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811210412566.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811210446030.png b/05.监控告警/01.Zabbix/image-20240811210446030.png
new file mode 100644
index 0000000..3512f2f
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811210446030.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811210609196.png b/05.监控告警/01.Zabbix/image-20240811210609196.png
new file mode 100644
index 0000000..072ec6d
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811210609196.png differ
diff --git a/05.监控告警/01.Zabbix/image-20240811210717780.png b/05.监控告警/01.Zabbix/image-20240811210717780.png
new file mode 100644
index 0000000..785c83d
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20240811210717780.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250215104654160.png b/05.监控告警/01.Zabbix/image-20250215104654160.png
new file mode 100644
index 0000000..6bb108f
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250215104654160.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143441157.png b/05.监控告警/01.Zabbix/image-20250316143441157.png
new file mode 100644
index 0000000..189e016
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143441157.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143522811.png b/05.监控告警/01.Zabbix/image-20250316143522811.png
new file mode 100644
index 0000000..4ed58c5
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143522811.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143612944.png b/05.监控告警/01.Zabbix/image-20250316143612944.png
new file mode 100644
index 0000000..d6d4511
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143612944.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143728527.png b/05.监控告警/01.Zabbix/image-20250316143728527.png
new file mode 100644
index 0000000..f44ddcc
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143728527.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143812080.png b/05.监控告警/01.Zabbix/image-20250316143812080.png
new file mode 100644
index 0000000..ab5aa11
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143812080.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316143838085.png b/05.监控告警/01.Zabbix/image-20250316143838085.png
new file mode 100644
index 0000000..87c4bb2
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316143838085.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316144001404.png b/05.监控告警/01.Zabbix/image-20250316144001404.png
new file mode 100644
index 0000000..8816601
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316144001404.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316144631981.png b/05.监控告警/01.Zabbix/image-20250316144631981.png
new file mode 100644
index 0000000..896fdbf
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316144631981.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316144759012.png b/05.监控告警/01.Zabbix/image-20250316144759012.png
new file mode 100644
index 0000000..de1626f
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316144759012.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316145451714.png b/05.监控告警/01.Zabbix/image-20250316145451714.png
new file mode 100644
index 0000000..481ff78
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316145451714.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316145719393.png b/05.监控告警/01.Zabbix/image-20250316145719393.png
new file mode 100644
index 0000000..184eaed
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316145719393.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316145750925.png b/05.监控告警/01.Zabbix/image-20250316145750925.png
new file mode 100644
index 0000000..ab2b30c
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316145750925.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316145935907.png b/05.监控告警/01.Zabbix/image-20250316145935907.png
new file mode 100644
index 0000000..62c6d5d
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316145935907.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316151257316.png b/05.监控告警/01.Zabbix/image-20250316151257316.png
new file mode 100644
index 0000000..b425369
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316151257316.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316151353990.png b/05.监控告警/01.Zabbix/image-20250316151353990.png
new file mode 100644
index 0000000..36dc02a
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316151353990.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152132163.png b/05.监控告警/01.Zabbix/image-20250316152132163.png
new file mode 100644
index 0000000..9f9e273
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152132163.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152222209.png b/05.监控告警/01.Zabbix/image-20250316152222209.png
new file mode 100644
index 0000000..aa27bbb
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152222209.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152330210.png b/05.监控告警/01.Zabbix/image-20250316152330210.png
new file mode 100644
index 0000000..cbcf1b6
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152330210.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152417222.png b/05.监控告警/01.Zabbix/image-20250316152417222.png
new file mode 100644
index 0000000..5857ca5
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152417222.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152509112.png b/05.监控告警/01.Zabbix/image-20250316152509112.png
new file mode 100644
index 0000000..476f4fa
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152509112.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152703035.png b/05.监控告警/01.Zabbix/image-20250316152703035.png
new file mode 100644
index 0000000..b045fa0
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152703035.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316152744501.png b/05.监控告警/01.Zabbix/image-20250316152744501.png
new file mode 100644
index 0000000..f874ece
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316152744501.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316153251565.png b/05.监控告警/01.Zabbix/image-20250316153251565.png
new file mode 100644
index 0000000..64c26d1
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316153251565.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316153912958.png b/05.监控告警/01.Zabbix/image-20250316153912958.png
new file mode 100644
index 0000000..a78f30b
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316153912958.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316154138064.png b/05.监控告警/01.Zabbix/image-20250316154138064.png
new file mode 100644
index 0000000..112e86f
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316154138064.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316154236124.png b/05.监控告警/01.Zabbix/image-20250316154236124.png
new file mode 100644
index 0000000..55c642e
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316154236124.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316155758866.png b/05.监控告警/01.Zabbix/image-20250316155758866.png
new file mode 100644
index 0000000..1a12bef
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316155758866.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316155845820.png b/05.监控告警/01.Zabbix/image-20250316155845820.png
new file mode 100644
index 0000000..79c8aa9
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316155845820.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316155928572.png b/05.监控告警/01.Zabbix/image-20250316155928572.png
new file mode 100644
index 0000000..cc287eb
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316155928572.png differ
diff --git a/05.监控告警/01.Zabbix/image-20250316165313573.png b/05.监控告警/01.Zabbix/image-20250316165313573.png
new file mode 100644
index 0000000..28c536d
Binary files /dev/null and b/05.监控告警/01.Zabbix/image-20250316165313573.png differ
diff --git a/05.监控告警/02.Prometheus.md b/05.监控告警/02.Prometheus.md
new file mode 100644
index 0000000..ef9fe3a
--- /dev/null
+++ b/05.监控告警/02.Prometheus.md
@@ -0,0 +1,1552 @@
+# 1. Prometheus监控系统
+
+# 2. Prometheus简介
+
+## 2.1 什么是Prometheus?
+
+Prometheus是由前 Google 工程师从 2012 年开始在 Soundcloud以开源软件的形式进行研发的系统监控和告警工具包,自此以后,许多公司和组织都采用了 Prometheus 作为监控告警工具。Prometheus 的开发者和用户社区非常活跃,它现在是一个独立的开源项目,可以独立于任何公司进行维护。为了证明这一点,Prometheus 于 2016 年 5 月加入CNCF基金会,成为继 Kubernetes 之后的第二个 CNCF 托管项目。
+
+## 2.2 Prometheus的优势
+
+Prometheus 的主要优势有:
+
+- 由指标名称和和键/值对标签标识的时间序列数据组成的多维数据模型
+- 强大的查询语言 PromQL
+- 不依赖分布式存储;单个服务节点具有自治能力。
+- 时间序列数据是服务端通过 HTTP 协议主动拉取获得的。
+- 也可以通过中间网关来推送时间序列数据
+- 可以通过静态配置文件或服务发现来获取监控目标。
+- 支持多种类型的图表和仪表盘。
+
+## 2.3 Prometheus的组件、架构
+
+Prometheus 的整体架构以及生态系统组件如下图所示:
+
+
+
+Prometheus Server 直接从监控目标中或者间接通过推送网关来拉取监控指标,它在本地存储所有抓取到的样本数据,并对此数据执行一系列规则,以汇总和记录现有数据的新时间序列或生成告警。可以通过 Grafana或者其他工具来实现监控数据的可视化。
+
+- **Prometheus server**是Prometheus架构中的**核心组件**,基于go语言编写而成,无第三方依赖关系,可以独立部署在物理服务器上、云主机、Docker容器内。主要用于收集每个目标数据,并存储为时间序列数据,对外可提供数据查询支持和告警规则配置管理。
+- Prometheus服务器可以对监控目标进行静态配置管理或者动态配置管理,**它将监控采集到的数据按照时间序列存储在本地磁盘的时序数据库中**(当然也支持远程存储),自身对外提供了自定义的PromQL语言,可以对数据进行查询和分析
+- Client Library是用于检测应用程序代码的客户端库。在监控服务之前,需要向客户端库代码添加检测实现Prometheus中metric的类型。
+- **Exporter**(数据采集)用于**输出被监控组件信息的HTTP**接口统称为Exporter(导出器)。目前互联网公司常用的组件大部分都有Expoter供**直接使用**,比如Nginx、MySQL、linux系统信息等。
+- **Pushgateway**是指用于支持短期临时或批量计划任务工作的汇聚节点。主要用于短期的job,此类存在的job时间较短,可能在Prometheus来pull之前就自动消失了。所以针对这类job,设计成可以直接向Pushgateway推送metric,这样Prometheus服务器端便可以定时去Pushgateway拉去metric
+ - Pushgateway是prometheus的一个组件,prometheus server默认是通过exporter主动获取数据(默认采取pull拉取数据),pushgateway则是通过被动方式推送数据到prometheus server,用户可以写一些自定义的监控脚本把需要监控的数据发送给pushgateway, 然后pushgateway再把数据发送给Prometheus server
+ - 总结就是pushgateway是prometheus的一个组件,是通过被动的方式将数据上传至prometheus。这个可以解决不在一个网段的问题
+- **Alertmanager**主要用于处理Prometheus服务器端发送的alerts信息,对其去除重数据、分组并路由到正确的接收方式,发出**告警**,支持丰富的告警方式。
+- **Service Discovery:**动态发现待监控的target,从而完成监控配置的重要组件,在容器环境中尤为重要,该组件目前由Prometheus Server内建支持
+
+参考博客:https://zhuanlan.zhihu.com/p/710612579
+
+## 2.4 Prometheus适用于什么场景
+
+Prometheus适用于记录**文本格式的时间序列**,它既适用于以机器为中心的监控,也适用于高度动态的面向服务的监控,在微服务的世界中,它对多维数据收集和查询的支持有特殊优势。Prometheus是专为提高系统可靠性而设计的,它可以在断电期间快速诊断问题,每个Prometheus Server都是相互独立的,不依赖于网络存储或者其他远程服务。当基础架构出现问题时,你可以通过Prometheus快速定位故障点,而且不会消耗大量的基础架构资源。
+
+## 2.5 Prometheus不适合什么场景
+
+Prometheus非常重视可靠性,即使在出现故障的情况下,你也可以随时统计有关系统的可用系统信息。如果你需要百分之百的准确度,例如按请求数量计费,那么Prometheus可能不太适合你,因为它收集的数据可能**不够详细完整精确**。
+
+# 3. Prometheus部署
+
+## 3.1 二进制部署
+
+1. 下载prometheus的二进制包
+
+ 官网地址:https://prometheus.io/download/
+
+```bash
+[root@server1 ~]# wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz
+```
+
+2. 获取软件包的哈希值,与官网提供的软件包的哈希值进行对比,保证下载的Prometheus软件包的完整性
+
+```bash
+[root@server1 ~]# sha256sum prometheus-2.47.0.linux-amd64.tar.gz
+277ad9f110ded8e326bc885848952941e839fa38dd3237e36415f0fa35a04424 prometheus-2.47.0.linux-amd64.tar.gz
+```
+
+3. 解压软件包到指定目录
+
+```bash
+[root@server1 ~]# mkdir /data
+[root@server1 ~]# tar -zxvf prometheus-2.47.0.linux-amd64.tar.gz -C /data/
+[root@server1 ~]# cd /data/
+[root@server1 data]# chown -R root:root /data/prometheus-2.47.0.linux-amd64
+[root@server1 data]# ln -sv prometheus-2.47.0.linux-amd64 prometheus
+"prometheus" -> "prometheus-2.47.0.linux-amd64"
+```
+
+### 3.1.1 前台启动
+
+1. 启动Prometheus,会输出如下信息,此时当终端关闭或者按下ctrl + c服务会自动关闭
+
+```bash
+[root@server1 data]# cd /data/prometheus
+[root@server1 prometheus]# ./prometheus
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:366 msg="No time or size retention was set so using the default time retention" duration=15d
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:404 msg="Starting Prometheus" version="(version=2.47.0, branch=HEAD, revision=a6be548dbc17780d562a39c0e4bd0bd4c00ad6e2)"
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:409 build_context="(go=go1.15.8, user=root@615f028225c9, date=20210217-14:17:24)"
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:410 host_details="(Linux 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 server1 (none))"
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:411 fd_limits="(soft=1024, hard=4096)"
+level=info ts=2021-02-28T06:03:36.885Z caller=main.go:412 vm_limits="(soft=unlimited, hard=unlimited)"
+level=info ts=2021-02-28T06:03:36.891Z caller=web.go:532 component=web msg="Start listening for connections" address=0.0.0.0:9090
+level=info ts=2021-02-28T06:03:36.895Z caller=main.go:779 msg="Starting TSDB ..."
+level=info ts=2021-02-28T06:03:36.897Z caller=tls_config.go:191 component=web msg="TLS is disabled." http2=false
+level=info ts=2021-02-28T06:03:36.930Z caller=head.go:668 component=tsdb msg="Replaying on-disk memory mappable chunks if any"
+level=info ts=2021-02-28T06:03:36.930Z caller=head.go:682 component=tsdb msg="On-disk memory mappable chunks replay completed" duration=5.69µs
+level=info ts=2021-02-28T06:03:36.930Z caller=head.go:688 component=tsdb msg="Replaying WAL, this may take a while"
+level=info ts=2021-02-28T06:03:36.933Z caller=head.go:740 component=tsdb msg="WAL segment loaded" segment=0 maxSegment=0
+level=info ts=2021-02-28T06:03:36.933Z caller=head.go:745 component=tsdb msg="WAL replay completed" checkpoint_replay_duration=38.416µs wal_replay_duration=2.357106ms total_replay_duration=2.638813ms
+level=info ts=2021-02-28T06:03:36.934Z caller=main.go:799 fs_type=XFS_SUPER_MAGIC
+level=info ts=2021-02-28T06:03:36.934Z caller=main.go:802 msg="TSDB started"
+level=info ts=2021-02-28T06:03:36.934Z caller=main.go:928 msg="Loading configuration file" filename=prometheus.yml
+```
+
+2. 新开一个窗口,检查端口号以及关闭防火墙和selinux
+
+```bash
+[root@server1 prometheus]# systemctl stop firewalld
+[root@server1 prometheus]# setenforce 0
+[root@server1 prometheus~]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port
+LISTEN 0 128 *:22 *:*
+LISTEN 0 100 127.0.0.1:25 *:*
+LISTEN 0 128 :::22 :::*
+LISTEN 0 100 ::1:25 :::*
+LISTEN 0 128 :::9090 :::*
+```
+
+### 3.1.2 检查配置文件
+
+在Prometheus日常维护中,一定会对配置文件prometheus.yml进行再编辑操作,通常对Prometheus服务进行重新启动操作即可完成对配置文件的加载。当然也可以通过动态的热加载来更新prometheus.yml中的配置信息
+查看进程id,向进程发送SIHHUP信号
+
+```bash
+# kill -HUP pid
+```
+
+通过HTTP API发送post请求到/-/reload
+
+```bash
+# curl -X POST http://localhost:9090/-/reload
+```
+
+- 检查配置文件的语法正确性
+
+```bash
+[root@server1 ~]# cd /data/prometheus
+[root@server1 prometheus]# ls
+console_libraries consoles data LICENSE NOTICE prometheus prometheus.yml promtool
+[root@server1 prometheus]# ./promtool check config prometheus.yml
+Checking prometheus.yml
+ SUCCESS: 0 rule files found
+```
+
+### 3.1.3 创建自启动脚本
+
+```bash
+[root@server1 ~]# vim /usr/lib/systemd/system/prometheus.service
+[Unit]
+Description=Prometheus Server
+Documentation=https://prometheus.io/docs/introduction/overview/
+After=network.target
+
+[Service]
+Type=simple
+Restart=on-failure
+ExecStart=/data/prometheus/prometheus \
+ --config.file=/data/prometheus/prometheus.yml \
+ --storage.tsdb.path=/data/prometheus/data \
+ --web.listen-address=:9090 \
+ --web.enable-lifecycle
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target
+```
+
+systemd重载配置以及启动prometheus
+
+```bash
+[root@server1 ~]# systemctl daemon-reload
+[root@server1 ~]# systemctl start prometheus
+[root@server1 prometheus]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port
+LISTEN 0 128 *:22 *:*
+LISTEN 0 100 127.0.0.1:25 *:*
+LISTEN 0 128 :::22 :::*
+LISTEN 0 100 ::1:25 :::*
+LISTEN 0 128 :::9090 :::*
+```
+
+### 3.1.4 浏览器访问测试
+
+
+
+# 4. Exporter
+
+## 4.1 简介
+
+在Prometheus的核心组件中,Exporter是重要的组成部分,在实际中**监控样本数据的收集**都是由Exporter完成的,Prometheus服务器只需要定时从这些Exporter提供的HTTP服务获取数据即可。官方提供了多种常用的Exporter,比如用于对数据库监控的mysqld_exporter和redis_exporter等。
+
+Exporter本质上是将收集的数据转化为对应的文本格式,并提供HTTP接口,供Prometheus定期采集数据。
+
+## 4.2 Exporter类型
+
+- 直接采集型
+ - 这类Exporter直接内置了响应的应用程序,用于向Prometheus直接提供target数据支持。这样设计的好处是,可以更好地监控各自系统内部的运行状态,同时也适合更多自定义监控指标的项目实施。
+- 间接采集型
+ - 原始监控目标并不直接支持Prometheus,需要我们使用Prometheus提供的客户端库编写该监控目标的监控采集数据,用户可以将该程序独立运行,取获取指定的各类监控数据值。例如,由于Linux操作系统自身并不能直接支持Prometheus,用户无法从操作系统层面上直接提供对Prometheus的支持,因此单独提供Node Exporter,还有数据库或网站HTTP应用类等Exporter。
+
+## 4.3 文本数据格式
+
+在Prometheus的监控环境中,所有返回监控样本数据的Exporter程序,均需要遵守Prometheus规范,即基于文本的数据格式,其特点是具有更好的跨平台和可读性。
+
+- 可以使用浏览器,或者通过curl工具来获得采集数据
+
+```bash
+# 以HELP开头的行,表示metric的帮助与说明解释,可以包含当前监控指标名称和对应的说明信息
+# 以TYPE开始的行,表示定义metric的类型
+# 以非#开头的行即监控样本的数据,包括metric_name{label_name1,label_name2...} value [timestamp可选项]
+
+[root@server1 ~]# curl 192.168.88.10:9090/metrics
+# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
+# TYPE go_gc_duration_seconds summary
+go_gc_duration_seconds{quantile="0"} 9.4601e-05
+go_gc_duration_seconds{quantile="0.25"} 0.000141153
+go_gc_duration_seconds{quantile="0.5"} 0.000416738
+go_gc_duration_seconds{quantile="0.75"} 0.001050261
+go_gc_duration_seconds{quantile="1"} 0.008308442
+go_gc_duration_seconds_sum 0.014675204
+go_gc_duration_seconds_count 13
+# HELP go_goroutines Number of goroutines that currently exist.
+# TYPE go_goroutines gauge
+go_goroutines 32
+# HELP go_info Information about the Go environment.
+# TYPE go_info gauge
+go_info{version="go1.15.8"} 1
+# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
+# TYPE go_memstats_alloc_bytes gauge
+go_memstats_alloc_bytes 1.6849432e+07
+# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.
+# TYPE go_memstats_alloc_bytes_total counter
+go_memstats_alloc_bytes_total 6.016028e+07
+# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.
+# TYPE go_memstats_buck_hash_sys_bytes gauge
+go_memstats_buck_hash_sys_bytes 1.461736e+06
+# HELP go_memstats_frees_total Total number of frees.
+# TYPE go_memstats_frees_total counter
+go_memstats_frees_total 219435
+# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.
+# TYPE go_memstats_gc_cpu_fraction gauge
+go_memstats_gc_cpu_fraction 3.012333999853177e-05
+# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.
+# TYPE go_memstats_gc_sys_bytes gauge
+go_memstats_gc_sys_bytes 5.719272e+06
+```
+
+## 4.4 Linux主机监控
+
+Prometheus社区很活跃,提供了非常多类型的Exporter。可以在官网中找到自己想要的Exporter并进行下载https://prometheus.io/download/
+
+由于Linux操作系统自身并不支持Prometheus,所以Prometheus官方提供了go语言编写的Node Exporter来实现对Linux操作系统主机的监控数据采集。它提供了系统内部几乎所有的标准指标,如cpu、内存、磁盘空间、磁盘I/O、系统负载和网络带宽。另外它还提供了由内核公开的大量额外监控指标,从负载平均到主板温度等。
+
+### 4.4.1 安装Exporter
+
+1. 下载node exporter的二进制包并解压
+
+```bash
+[root@server2 ~]# wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
+[root@server2 ~]# mkdir /data
+[root@server2 ~]# tar -zxvf node_exporter-1.8.2.linux-amd64.tar.gz -C /data/
+node_exporter-1.8.2.linux-amd64/
+node_exporter-1.8.2.linux-amd64/NOTICE
+node_exporter-1.8.2.linux-amd64/node_exporter
+node_exporter-1.8.2.linux-amd64/LICENSE
+[root@server2 ~]# cd /data/
+[root@server2 data]# chown -R root:root node_exporter-1.8.2.linux-amd64/
+[root@server2 data]# ln -sv node_exporter-1.8.2.linux-amd64 node_exporter
+"node_exporter" -> "node_exporter-1.8.2.linux-amd64"
+```
+
+2. 启动node_exporter
+
+```bash
+[root@server2 node_exporter]# ./node_exporter
+```
+
+### 4.4.2 关联Prometheus server
+
+当启动node_exporter开始工作时,node_exporter和Prometheus server还没有进行关联,二者各自独立没有关联。
+
+可以在Prometheus server中,找到主机目录,找到主配置文件,使用其中的静态配置功能static_configs来采集node_exporter提供的数据
+
+**server主配置文件介绍:**
+
+```bash
+[root@server1 prometheus]# cat prometheus.yml
+# my global config
+global:
+ scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minut e.
+ evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
+ # scrape_timeout is set to the global default (10s).
+
+# Alertmanager configuration
+alerting:
+ alertmanagers:
+ - static_configs:
+ - targets:
+ # - alertmanager:9093
+
+# Load rules once and periodically evaluate them according to the global 'evaluation_interval' .
+rule_files:
+ # - "first_rules.yml"
+ # - "second_rules.yml"
+
+# A scrape configuration containing exactly one endpoint to scrape:
+# Here it's Prometheus itself.
+scrape_configs:
+ # The job name is added as a label `job=
+
+### 4.4.4 metricts数据采集
+
+`node_exporter` 是 Prometheus 生态系统中的一个重要组件,用于收集主机级别的系统指标(如 CPU、内存、磁盘、网络等)。以下是 `node_exporter` 常见的监控项及其含义
+
+#### 4.4.4.1 常见采集项
+
+1. **CPU 相关指标**
+
+- `node_cpu_seconds_total`:CPU 在每个模式(user、system、idle 等)下的使用时间(秒)。
+ - 模式包括:`user`(用户态)、`system`(内核态)、`idle`(空闲)、`iowait`(等待 I/O)等。
+- **`node_cpu_cores`**:CPU 核心数。
+- **`node_cpu_frequency_hertz`**:CPU 频率。
+
+------
+
+2. **内存相关指标**
+
+- **`node_memory_MemTotal_bytes`**:系统总内存大小。
+- **`node_memory_MemFree_bytes`**:空闲内存大小。
+- **`node_memory_Buffers_bytes`**:缓冲区使用的内存大小。
+- **`node_memory_Cached_bytes`**:缓存使用的内存大小。
+- **`node_memory_SwapTotal_bytes`**:交换分区总大小。
+- **`node_memory_SwapFree_bytes`**:空闲交换分区大小。
+
+------
+
+3. **磁盘相关指标**
+
+- **`node_disk_read_bytes_total`**:磁盘读取的总字节数。
+- **`node_disk_written_bytes_total`**:磁盘写入的总字节数。
+- **`node_disk_reads_completed_total`**:完成的磁盘读取操作数。
+- **`node_disk_writes_completed_total`**:完成的磁盘写入操作数。
+- **`node_disk_io_time_seconds_total`**:磁盘 I/O 操作的总时间。
+- **`node_filesystem_size_bytes`**:文件系统总大小。
+- **`node_filesystem_free_bytes`**:文件系统空闲大小。
+
+------
+
+4. **网络相关指标**
+
+- **`node_network_receive_bytes_total`**:网络接口接收的总字节数。
+- **`node_network_transmit_bytes_total`**:网络接口发送的总字节数。
+- **`node_network_receive_packets_total`**:网络接口接收的数据包总数。
+- **`node_network_transmit_packets_total`**:网络接口发送的数据包总数。
+
+------
+
+5. **系统负载相关指标**
+
+- **`node_load1`**:1 分钟内的系统平均负载。
+- **`node_load5`**:5 分钟内的系统平均负载。
+- **`node_load15`**:15 分钟内的系统平均负载。
+
+------
+
+6. **进程相关指标**
+
+- **`node_procs_running`**:当前正在运行的进程数。
+- **`node_procs_blocked`**:当前被阻塞的进程数。
+
+------
+
+7. **文件描述符相关指标**
+
+- **`node_filefd_allocated`**:已分配的文件描述符数量。
+- **`node_filefd_maximum`**:文件描述符的最大数量。
+
+------
+
+8. **时间相关指标**
+
+- **`node_time_seconds`**:当前系统时间(Unix 时间戳)。
+- **`node_boot_time_seconds`**:系统启动时间(Unix 时间戳)。
+
+------
+
+9. **其他指标**
+
+- **`node_uname_info`**:系统信息(如内核版本、操作系统等)。
+- **`node_os_info`**:操作系统信息。
+
+#### 4.4.4.2 示例
+
+一、CPU 在每个模式(user、system、idle 等)下的使用时间(秒)
+
+node_cpu_seconds_total
+
+
+
+可以通过PromQL(后面会介绍这种查询语言)表达式进行查询,计算每核cpu每秒的空闲时间,然后对主机上的所有cpu求平均值
+
+`avg without(cpu,mode) (rate(node_cpu_seconds_total {mode="idle"} [1m]))`
+
+
+
+二、内存信息采集
+
+当前主机内存查看
+
+```bash
+[root@server2 node_exporter]# free -b
+ total used free shared buff/cache available
+Mem: 1907970048 112123904 1564102656 10014720 231743488 1609289728
+Swap: 2147479552 0 2147479552
+```
+
+总内存:node_memory_MemTotal_bytes
+
+
+
+空闲内存:node_memory_MemFree_bytes
+
+
+
+三、磁盘信息采集
+
+磁盘 I/O 操作的总时间:node_disk_io_time_seconds_total
+
+
+
+四、文件系统采集
+
+node_filesystem_size_bytes
+
+
+
+五、网络信息采集
+
+node_network_info
+
+
+
+任意一个Exporter都会提供足够多的metric,我们在学习的时候也不需要关心具体有多少metric,每个metric具体意思(其实见名知义大概也可以猜到)
+
+## 4.5 MySQL监控
+
+### 4.5.1 部署MySQL环境
+
+```bash
+[root@server2 ~]# yum install -y mariadb-server
+# 启动mariadb数据库
+[root@server2 ~]# systemctl enable --now mariadb
+# 初始化数据库并设置密码
+[root@server2 ~]# mysqladmin -uroot password '123456'
+# 测试数据库连接是否正常
+[root@server2 ~]# mysql -uroot -p123456 -e "show databases;"
++--------------------+
+| Database |
++--------------------+
+| information_schema |
+| mysql |
+| performance_schema |
+| test |
++--------------------+
+
+# 创建exporter用户
+ariaDB [(none)]> grant all privileges on *.* to mysqld_exporter@'localhost' identified by '123456';
+Query OK, 0 rows affected (0.00 sec)
+# 刷新账户信息
+MariaDB [(none)]> flush privileges;
+Query OK, 0 rows affected (0.00 sec)
+```
+
+### 4.5.2 安装Exporter
+
+官网下载mysqld_exporter二进制包解压缩
+
+```bash
+[root@server2 ~]# wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.15.1/mysqld_exporter-0.15.1.linux-amd64.tar.gz
+[root@server2 ~]# tar -zxvf mysqld_exporter-0.15.1.linux-amd64.tar.gz -C /data/
+mysqld_exporter-0.15.1.linux-amd64/
+mysqld_exporter-0.15.1.linux-amd64/LICENSE
+mysqld_exporter-0.15.1.linux-amd64/mysqld_exporter
+mysqld_exporter-0.15.1.linux-amd64/NOTICE
+[root@server2 ~]# cd /data/
+[root@server2 data]# chown -R root:root mysqld_exporter-0.15.1.linux-amd64/
+[root@server2 data]# ln -sv mysqld_exporter-0.15.1.linux-amd64/ mysqld_exporter
+"mysqld_exporter" -> "mysqld_exporter-0.15.1.linux-amd64/"
+```
+
+### 4.5.3 配置Exporter
+
+```bash
+[root@server2 mysqld_exporter]# pwd
+/data/mysqld_exporter
+
+# 创建一个配置文件.mysqld_exporter.cnf
+[root@server2 mysqld_exporter]# vim .mysqld_exporter.cnf
+[client]
+user=mysqld_exporter
+password=123456
+
+[root@server2 mysqld_exporter]# ./mysqld_exporter --config.my-cnf='.mysqld_exporter.cnf' &
+[root@server2 mysqld_exporter]# ss -nlt
+State Recv-Q Send-Q Local Address:Port Peer Address:Port
+LISTEN 0 50 *:3306 *:*
+LISTEN 0 128 *:22 *:*
+LISTEN 0 100 127.0.0.1:25 *:*
+LISTEN 0 128 :::9100 :::*
+LISTEN 0 128 :::9104 :::*
+LISTEN 0 128 :::22 :::*
+LISTEN 0 100 ::1:25 :::*
+```
+
+### 4.5.4 关联Prometheus server
+
+```bash
+[root@server1 prometheus]# vim prometheus.yml
+ - job_name: 'mysqld_exporter'
+ scrape_interval: 10s
+ static_configs:
+ - targets: [192.168.88.20:9104]
+
+[root@server1 prometheus]# ./promtool check config prometheus.yml
+Checking prometheus.yml
+ SUCCESS: prometheus.yml is valid prometheus config file syntax
+
+[root@server1 prometheus]# systemctl restart prometheus
+```
+
+
+
+### 4.5.5 metricts数据采集
+
+MySQL数据库的性能状态监控内容非常多,但通常必不可少的内容包括查询吞吐量、查询执行性能、连接情况、缓冲池使用情况等。
+
+#### 4.5.5.1 常见采集项
+
+1. **MySQL状态信息**:
+ - `mysql_global_status_connections`: 当前连接数。
+ - `mysql_global_status_threads_connected`: 当前连接的线程数。
+ - `mysql_global_status_threads_running`: 当前正在运行的线程数。
+
+----
+
+2. **查询性能**:
+
+- `mysql_global_status_questions`: 服务器启动以来执行的查询总数。
+- `mysql_global_status_slow_queries`: 慢查询的数量。
+
+----
+
+3. **连接和线程**:
+
+- `mysql_global_status_max_used_connections`: 服务器启动以来同时使用的最大连接数。
+- `mysql_global_status_aborted_connects`: 失败的连接尝试次数。
+
+----
+
+4. **InnoDB存储引擎**:
+
+- `mysql_global_status_innodb_buffer_pool_read_requests`: InnoDB缓冲池的读请求次数。
+- `mysql_global_status_innodb_buffer_pool_reads`: 从磁盘读取的次数。
+- `mysql_global_status_innodb_buffer_pool_pages_free`: InnoDB缓冲池中空闲的页数。
+- `mysql_global_status_innodb_row_lock_waits`: InnoDB行锁等待的次数。
+
+----
+
+5. **网络流量**:
+
+- `mysql_global_status_bytes_received`: 从所有客户端接收的字节数。
+- `mysql_global_status_bytes_sent`: 发送到所有客户端的字节数。
+
+----
+
+6. **表缓存**:
+
+- `mysql_global_status_table_open_cache_hits`: 表缓存命中次数。
+- `mysql_global_status_table_open_cache_misses`: 表缓存未命中次数。
+
+----
+
+7. **复制状态**(如果启用了复制):
+
+- `mysql_slave_status_slave_io_running`: 从库I/O线程是否正在运行。
+- `mysql_slave_status_slave_sql_running`: 从库SQL线程是否正在运行。
+- `mysql_slave_status_seconds_behind_master`: 从库落后主库的秒数。
+
+#### 4.5.5.2 示例
+
+一、查询吞吐量,MySQL客户端应用程序发送的所有查询语句,该计数器都是递增的
+
+mysql_global_status_questions
+
+
+
+二、查询执行性能,每当查询时间超过预先设定的慢查询时间计数器都会递增
+
+mysql_global_status_slow_queries
+
+
+
+三、连接情况,查询MySQL所设置的最大连接数,防止连接数量过大导致服务器过载运行
+
+mysql_global_variables_max_connections
+
+
+
+四、查看当前连接数
+
+mysql_global_status_threads_connected
+
+
+
+五、缓存池使用情况
+
+mysql_global_status_innodb_buffer_pool_bytes_data4
+
+
+
+Prometheus大多数情况下,显示的默认单位为字节,必要时候,可以自己进行单位换算
+
+mysql_global_status_innodb_buffer_pool_bytes_data/1024/1024
+
+存储单位通常以 **1024** 为基数进行换算(二进制方式),但在某些场景下也可能以 **1000** 为基数(十进制方式)。以下是常见的存储单位及其换算关系:
+
+| 单位 | 缩写 | 换算关系(二进制) | 换算关系(十进制) |
+| :----- | :--- | :------------------------------- | :------------------------------- |
+| 字节 | B | 1 B = 8 bit | 1 B = 8 bit |
+| 千字节 | KB | 1 KB = 1024 B | 1 KB = 1000 B |
+| 兆字节 | MB | 1 MB = 1024 KB = 1,048,576 B | 1 MB = 1000 KB = 1,000,000 B |
+| 吉字节 | GB | 1 GB = 1024 MB = 1,073,741,824 B | 1 GB = 1000 MB = 1,000,000,000 B |
+| 太字节 | TB | 1 TB = 1024 GB | 1 TB = 1000 GB |
+| 拍字节 | PB | 1 PB = 1024 TB | 1 PB = 1000 TB |
+| 艾字节 | EB | 1 EB = 1024 PB | 1 EB = 1000 PB |
+| 泽字节 | ZB | 1 ZB = 1024 EB | 1 ZB = 1000 EB |
+| 尧字节 | YB | 1 YB = 1024 ZB | 1 YB = 1000 ZB |
+
+# 5. 服务发现
+
+Prometheus服务发现能够自动化检测分类,并且能够识别新目标和变更目标。也就是说,可以自动发现并监控目标或变更目标,动态进行数据采集和处理。
+
+## 5.1 基于文件的服务发现
+
+- 准备JSON格式的文件
+
+```bash
+[root@server1 ~]# cd /data/prometheus
+[root@server1 prometheus]# mkdir targets
+[root@server1 prometheus]# vim targets/dev_node.json
+[{
+ "targets": [ "192.168.88.20:9100","192.168.88.20:9104" ],
+ "labels": {
+ "env": "dev_webgame"
+ }
+}]
+-------------------------------------------------------------------
+或者这里是准备yaml文件,那么下面相应的配置文件需要与yaml匹配
+vim targets/dev_node.yml
+- targets:
+ - "192.168.88.20:9100"
+ - "192.168.88.20:9104"
+```
+
+- 修改配置文件
+
+```bash
+[root@server1 prometheus]# vim /data/prometheus/prometheus.yml
+ - job_name: 'node_service_discovery'
+ file_sd_configs:
+ - files:
+ - targets/*.yml
+ refresh_interval: 60s
+```
+
+- 重新启动服务
+
+扩展:这是基于文件发现,还有基于consul基于dns的服务发现,这个自行扩展。
+
+# 6. 相关概念
+
+## 6.1 Jobs和Instances
+
+在Prometheus中,任何被采集的目标,即每一个暴露监控样本数据的HTTP服务都称为**一个实例instance**,**通常对应于单个进程**。而**具有相同采集目的实例集合称为作业job**。
+
+## 6.2 数据模型
+
+Prometheus所有采集的监控数据均以**指标的形式**保存在内置的时间序列数据库当中(TSDB):属于同一**指标名称**、同一**标签**集合的、有**时间戳**标记的数据流。除了存储的时间序列,Prometheus还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。
+
+### 6.2.1 指标名称和标签
+
+每一条时间序列由指标名称(Metric Name)以及一组标签(键值对)唯一标识。其中指标的名称(Metric Name)可以反映被监控样本的含义(例如,http_request_total可以看出来表示当前系统接收到的http请求总量),指标名称只能由ASCII字符、数字、下划线以及冒号组成,同时必须匹配正则表达式`[a-zA-Z_:][a-zA-Z0-9_:]*`。
+
+**注意**
+
+冒号用来表示用户自定义的记录规则,不能在 exporter 中或监控对象直接暴露的指标中使用冒号来定义指标名称。
+
+通过使用标签,Prometheus开启了强大的多维数据模型:对于相同的指标名称,通过不同标签列表的集合,会形成特定的度量维度实例(例如,所有包含度量名称为 `/api/tracks` 的 http 请求,打上 `method=POST` 的标签,就会形成具体的 http 请求)。查询语言在这些指标和标签列表的基础上进行过滤和聚合,改变任何度量指标上的任何标签值(包括添加或删除指标),都会创建新的时间序列。
+
+标签的名称只能由ASCII字符、数字、以及下划线组成并满足正则表达式`[a-zA-Z_][a-zA-Z0-9_]*`。其中以 `__` 作为前缀的标签,是系统保留的关键字,只能在系统内部使用。标签的值则可以包含任何 `Unicode` 编码的字符。
+
+### 6.2.2 样本
+
+在时间序列中的每一个点称为样本,样本由以下三部分组成:
+
+- 指标(metric):指标名称和描述当前样本特征的labelset;
+- 时间戳:一个精确到时间毫秒的时间戳
+- 样本值:一个浮点型数据表示当前样本的值
+
+### 6.2.3 表示方式
+
+通过如下表示方式表示指定名称和指定标签集合的时间序列
+
+```
+