Skip to main content

基础面试题

Linux系统

路由交换

交换机: 涉及vlan,stp协议

路由器: static router, 动态路由BGP,RIP,OSPF

介绍vxlan, vlan的区别,物理网络 underlay, overlay叠加网络

https://segmentfault.com/a/1190000022365692

image-20231104000823756

Raid,LVM服务器

Raid相关概念:

Raid0: 没有冗余,性能最好,冗余最差,2块起 磁盘使用率100%

Raid1: 冗余最好, 但是性能最差 ,2块起,最多允许坏 磁盘使用率50%

Raid5: 不管多少数据盘,最多只能坏一块盘。磁盘使用率(N-1)/N

Raid10:

  1. RAID 0+1是存储性能和数据安全兼顾的方案。它在提供与RAID 1一样的数据安全保障的同时,也提供了与RAID 0近似的存储性能。

  2. 由于RAID 0+1也通过数据的100%备份提供数据安全保障,因此RAID 0+1的磁盘空间利用率与RAID 1相同,存储成本高。

  3. RAID 0+1的特点使其特别适用于既有大量数据需要存取,同时又对数据安全性要求严格的领域,如银行、金融、商业超市、仓储库房、各种档案管理等。

KVM

基本理论

什么是虚拟化?就是将一台物理机虚拟成多台虚拟机,虚拟机之前互不干扰。

为什么要用虚拟化?充分利用物理资源,提供冗余性、向云计算演进的必要基础。

常见的虚拟化软件?vmware、kvm

查看当前系统是使用哪家的虚拟化?lscpu

kvm的三个组件及作用:libvirt(用来管理虚拟机)、virt(安装和克隆虚拟机)、qemu(管理虚拟机磁盘的)

磁盘的类型(raw/qcow2),raw不支持快照但性能好,常用的是qcom2支持快照,性能相比差一点。

第一个虚拟要默认是侦听在5900这个端口。

桥接的工作原理

注意:

参考容器章节-比对kvm跟容器的区别

iptables

表和链(四表五链) 1.filter (过滤) 进行包过滤处理的一张表 2.nat (映射) 对数据地址信息进行转换/数据包端口信息进行转换 实现内网用户访问外网 实现外网用户访问内网 3.mangle (不常用) 对数据包信息进行标记 4.raw(不常用

image-20231102191014927

只允许远程主机访问本机的80端口

ptables -P INPUT DROP

iptables -A INPUT --dport 80 -j ACCEPT

硬链接和软链接的区别

1)硬链接

由于 Linux 下的文件是通过索引节点(inode)来识别文件,硬链接可以认为是一个指针,指向文件索引节点的指针,系统并不为它重新分配 inode 。每添加一个一个硬链接,文件的链接数就加 1 。

  • 不足:1)不可以在不同文件系统的文件间建立链接;2)只有超级用户才可以为目录创建硬链接。

2)软链接

软链接克服了硬链接的不足,没有任何文件系统的限制,任何用户可以创建指向目录的符号链接。因而现在更为广泛使用,它具有更大的灵活性,甚至可以跨越不同机器、不同网络对文件进行链接。

  • 不足:因为链接文件包含有原文件的路径信息,所以当原文件从一个目录下移到其他目录中,再访问链接文件,系统就找不到了,而硬链接就没有这个缺陷,你想怎么移就怎么移;还有它要系统分配额外的空间用于建立新的索引节点和保存原文件的路径。

实际场景下,基本是使用软链接。总结区别如下:

  • 硬链接不可以跨分区,软件链可以跨分区。
  • 硬链接指向一个 inode 节点,而软链接则是创建一个新的 inode 节点。
  • 删除硬链接文件,不会删除原文件,删除软链接文件,会把原文件删除。

Linux中的软限制和硬限制的区别是

在Linux中,软限制是系统为了保护文件系统而设置的一个限制,当达到软限制时,系统会发出警告,但仍然允许操作。而硬限制则是系统为了保护文件系统而设置的一个绝对限制,当达到硬限制时,系统将禁止操作

Linux 开机启动过程

  • 1、主机加电自检,加载 BIOS 硬件信息
  • 2、读取 MBR 的引导文件(GRUB、LILO)
  • 3、引导 Linux 内核
  • 4、运行第一个进程 init (进程号永远为 1 )
  • 5、进入相应的运行级别
  • 6、运行终端,输入用户名和密码

Linux 使用的进程间通信方式

  • 1、管道(pipe)、流管道(s_pipe)、有名管道(FIFO)
  • 2、信号(signal)
  • 3、消息队列
  • 4、共享内存
  • 5、信号量
  • 6、套接字(socket)

less命令

(1)ps 查看进程信息并通过 less 分页显示

ps -aux | less -N

(2)查看多个文件

less 1.log 2.log

可以使用 n 查看下一个,使用 p 查看前一个。

ln 命令

功能是为文件在另外一个位置建立一个同步的链接,当在不同目录需要该问题时,就不需要为每一个目录创建同样的文件,通过 ln 创建的链接(link)减少磁盘占用量。

链接分类:软件链接及硬链接

软链接:

  • 1.软链接,以路径的形式存在。类似于Windows操作系统中的快捷方式
  • 2.软链接可以 跨文件系统 ,硬链接不可以
  • 3.软链接可以对一个不存在的文件名进行链接
  • 4.软链接可以对目录进行链接

硬链接:

  • 1.硬链接,以文件副本的形式存在。但不占用实际空间。
  • 2.不允许给目录创建硬链接
  • 3.硬链接只有在同一个文件系统中才能创建

需要注意

  • 第一:ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化;
  • 第二:ln的链接又分软链接和硬链接两种,软链接就是ln –s 源文件 目标文件,它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间,硬链接 ln 源文件 目标文件,没有参数-s, 它会在你选定的位置上生成一个和源文件大小相同的文件,无论是软链接还是硬链接,文件都保持同步变化。
  • 第三:ln指令用在链接文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则会把前面指定的所有文件或目录复制到该目录中。若同时指定多个文件或目录,且最后的目的地并非是一个已存在的目录,则会出现错误信息。

常用参数

-b 删除,覆盖以前建立的链接
-s 软链接(符号链接)
-v 显示详细处理过程

实例

(1)给文件创建软链接,并显示操作信息

ln -sv source.log link.log

(2)给文件创建硬链接,并显示操作信息

ln -v source.log link1.log

(3)给目录创建软链接

ln -sv /opt/soft/test/test3 /opt/soft/test/test5

locate 命令

locate 通过搜寻系统内建文档数据库达到快速找到档案,数据库由 updatedb 程序来更新,updatedb 是由 cron daemon 周期性调用的。默认情况下 locate 命令在搜寻数据库时比由整个由硬盘资料来搜寻资料来得快,但较差劲的是 locate 所找到的档案若是最近才建立或 刚更名的,可能会找不到,在内定值中,updatedb 每天会跑一次,可以由修改 crontab 来更新设定值 (etc/crontab)。

locate 与 find 命令相似,可以使用如 *、? 等进行正则匹配查找

常用参数

-l num(要显示的行数)
-f 将特定的档案系统排除在外,如将proc排除在外
-r 使用正则运算式做为寻找条件

实例

(1)查找和 pwd 相关的所有文件(文件名中包含 pwd)

locate pwd

(2)搜索 etc 目录下所有以 sh 开头的文件

locate /etc/sh

(3)查找 /var 目录下,以 reason 结尾的文件

locate -r '^/var.*reason$'(其中.表示一个字符,*表示任务多个;.*表示任意多个字符)

其他参考

Java-review-gudie/面试题集/Linux面试题.md at master · ThinkingHan/Java-review-gudie · GitHub

shell脚本

变量引用

$name 或者 ${name}

命令引用:

Name=`command` 或者 name =$(command)

查看变量 set

删除变量: unset name

环境变量:

Export name=value 或者  declare -x name=value

查看环境变量; env ,printenv ,export,declare -x

只读变量: 只能申明定义,后续不能修改

Readonly name , declare -r name

参数

1、$#:表示执行脚本传入参数的个数
2、$*:表示执行脚本传入参数的列表(不包括$0)
3、$$:表示进程的id;Shell本身的PID(ProcessID,即脚本运行的当前 进程ID号)
4、$!:Shell最后运行的后台Process的PID(后台运行的最后一个进程的 进程ID号)
5、$@:表示执行脚本传入参数的所有个数(不包括$0)
6、$0:表示执行的脚本名称
7、$1:表示第一个参数
8、$2:表示第二个参数
9、$?:表示脚本执行的状态,0表示正常,其他表示错误

​ Set - - 清空所有的位置变量

退出状态码变量:

​ $? 值为0 成功, $? 1-255代表失败

​ #生成 0 - 49 之间随机数 echo $[$RANDOM%50]

#随机字体颜色 [root@centos8 ~]#echo -e "\033[1;$[RANDOM%7+31]mmagedu\033[0m"

-gt 是否大于
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
-z "STRING" 字符串是否为空,空为真,不空为假
-n "STRING" 字符串是否不空,不空为真,空为假
\> ascii码是否大于ascii码

=~ 左侧字符串是否能够被右侧的PATTERN所匹配 注意: 此表达式用于[[ ]]中;扩展的正则表达式

文件测试

-a FILE:同 -e 
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件

配置文件执行顺序:

/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

profile类和bashrc类

profile类为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh

个人:~/.bash_profile

功用:

(1) 用于定义环境变量

(2) 运行命令或脚本

Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置

(1) 全局:/etc/bashrc

(2) 个人:~/.bashrc

功用: (1) 定义命令别名和函数 (2) 定义本地变量

条件判断case语句

case 变量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...

*)

默认分支

;;

esac

image-20231102185004617

#返回字符串变量var的长度 ${#var}

linux namespace

对于容器技术而言,它实现资源层面上的限制和隔离,依赖于 Linux 内核所提供的 cgroup 和 namespace 技术。

我们先对这两项技术的作用做个概括:

  • cgroup 的主要作用:管理资源的分配、限制;
  • namespace 的主要作用:封装抽象,限制,隔离,使命名空间内的进程看起来拥有他们自己的全局资源;

本篇,我们重点来聊 namespace 。

最早期 - Plan 9

我们引用 wiki 上对 namespace 的定义:

Namespaces are a feature of the Linux kernel that partitions kernel resources such that one set of processes sees one set of resources while another set of processes sees a different set of resources. The feature works by having the same namespace for a set of resources and processes, but those namespaces refer to distinct resources.

namespace 是 Linux 内核的一项特性,它可以对内核资源进行分区,使得一组进程可以看到一组资源;而另一组进程可以看到另一组不同的资源。该功能的原理是为一组资源和进程使用相同的 namespace,但是这些 namespace 实际上引用的是不同的资源。

这样的说法未免太绕了些,简单来说 namespace 是由 Linux 内核提供的,用于进程间资源隔离的一种技术。将全局的系统资源包装在一个抽象里,让进程(看起来)拥有独立的全局资源实例。同时 Linux 也默认提供了多种 namespace,用于对多种不同资源进行隔离。

在之前,我们单独使用 namespace 的场景比较有限,但 namespace 却是容器化技术的基石。

我们先来看看它的发展历程。

最早期 - Plan 9

img

图 1 ,namespace 的历史过程

最早期 - Plan 9

namespace 的早期提出及使用要追溯到 Plan 9 from Bell Labs ,贝尔实验室的 Plan 9。这是一个分布式操作系统,由贝尔实验室的计算科学研究中心在八几年至02年开发的(02年发布了稳定的第四版,距离92年发布的第一个公开版本已10年打磨),现在仍然被操作系统的研究者和爱好者开发使用。在 Plan 9 的设计与实现中,我们着重提以下3点内容:

  • 文件系统:所有系统资源都列在文件系统中,以 Node 标识。所有的接口也作为文件系统的一部分呈现。
  • Namespace:能更好的应用及展示文件系统的层次结构,它实现了所谓的 “分离”和“独立”。
  • 标准通信协议:9P协议(Styx/9P2000)。

img

图 2 ,Plan 9 from Bell Labs 图标

开始加入 Linux Kernel

Namespace 开始进入 Linux Kernel 的版本是在 2.4.X,最初始于 2.4.19 版本。但是,自 2.4.2 版本才开始实现每个进程的 namespace。

img

图 3 ,Linux Kernel Note

img

图 4 ,Linux Kernel 对应的各操作系统版本

Linux 3.8 基本实现

Linux 3.8 中终于完全实现了 User Namespace 的相关功能集成到内核。这样 Docker 及其他容器技术所用到的 namespace 相关的能力就基本都实现了。

img

图 5 ,Linux Kernel 从 2001 到2013 逐步演变,完成了 namespace 的实现

Namespace 类型

namespace名称使用的标识 - Flag控制内容
CgroupCLONE_NEWCGROUPCgroup root directory cgroup 根目录
IPCCLONE_NEWIPCSystem V IPC, POSIX message queues信号量,消息队列
NetworkCLONE_NEWNETNetwork devices, stacks, ports, etc.网络设备,协议栈,端口等等
MountCLONE_NEWNSMount points挂载点
PIDCLONE_NEWPIDProcess IDs进程号
TimeCLONE_NEWTIME时钟
UserCLONE_NEWUSER用户和组 ID
UTSCLONE_NEWUTS系统主机名和 NIS(Network Information Service) 主机名(有时称为域名)

Cgroup namespaces

Cgroup namespace 是进程的 cgroups 的虚拟化视图,通过 /proc/[pid]/cgroup/proc/[pid]/mountinfo 展示。

使用 cgroup namespace 需要内核开启 CONFIG_CGROUPS 选项。可通过以下方式验证:

(MoeLove) ➜ grep CONFIG_CGROUPS /boot/config-$(uname -r)
CONFIG_CGROUPS=y

cgroup namespace 提供的了一系列的隔离支持:

  • 防止信息泄漏(容器不应该看到容器外的任何信息)。
  • 简化了容器迁移。
  • 限制容器进程资源,因为它会把 cgroup 文件系统进行挂载,使得容器进程无法获取上层的访问权限。

每个 cgroup namespace 都有自己的一组 cgroup 根目录。这些 cgroup 的根目录是在 /proc/[pid]/cgroup 文件中对应记录的相对位置的基点。当一个进程用 CLONE_NEWCGROUP(clone(2) 或者 unshare(2)) 创建一个新的 cgroup namespace时,它当前的 cgroups 的目录就变成了新 namespace 的 cgroup 根目录。

(MoeLove) ➜ cat /proc/self/cgroup 
0::/user.slice/user-1000.slice/session-2.scope

当一个目标进程从 /proc/[pid]/cgroup 中读取 cgroup 关系时,每个记录的路径名会在第三字段中展示,会关联到正在读取的进程的相关 cgroup 分层结构的根目录。如果目标进程的 cgroup 目录位于正在读取的进程的 cgroup namespace 根目录之外时,那么,路径名称将会对每个 cgroup 层次中的上层节点显示 ../

我们来看看下面的示例(这里以 cgroup v1 为例,如果你想看 v2 版本的示例,请在留言中告诉我):

  1. 在初始的 cgroup namespace 中,我们使用 root (或者有 root 权限的用户),在 freezer 层下创建一个子 cgroup 名为 moelove-sub,同时,将进程放入该 cgroup 进行限制。
(MoeLove) ➜ mkdir -p /sys/fs/cgroup/freezer/moelove-sub
(MoeLove) ➜ sleep 6666666 &
[1] 1489125
(MoeLove) ➜ echo 1489125 > /sys/fs/cgroup/freezer/moelove-sub/cgroup.procs
  1. 我们在 freezer 层下创建另外一个子 cgroup,名为 moelove-sub2, 并且再放入执行进程号。可以看到当前的进程已经纳入到 moelove-sub2的 cgroup 下管理了。
(MoeLove) ➜ mkdir -p /sys/fs/cgroup/freezer/moelove-sub2
(MoeLove) ➜ echo $$
1488899
(MoeLove) ➜ echo 1488899 > /sys/fs/cgroup/freezer/moelove-sub2/cgroup.procs
(MoeLove) ➜ cat /proc/self/cgroup |grep freezer
7:freezer:/moelove-sub2
  1. 我们使用 unshare(1) 创建一个进程,这里使用了 -C参数表示是新的 cgroup namespace, 使用了 -m参数表示是新的 mount namespace。
(MoeLove) ➜ unshare -Cm bash
root@moelove:~#
  1. 从用 unshare(1) 启动的新 shell 中,我们可以在 /proc/[pid]/cgroup 文件中看到,新 shell 和以上示例中的进程:
root@moelove:~# cat /proc/self/cgroup | grep freezer
7:freezer:/
root@moelove:~# cat /proc/1/cgroup | grep freezer
7:freezer:/..

# 第一个示例进程
root@moelove:~# cat /proc/1489125/cgroup | grep freezer
7:freezer:/../moelove-sub
  1. 从上面的示例中,我们可以看到新 shell 的 freezer cgroup 关系中,当新的 cgroup namespace 创建时,freezer cgroup 的根目录与它的关系也就建立了。
root@moelove:~# cat /proc/self/mountinfo | grep freezer
1238 1230 0:37 /.. /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime - cgroup cgroup rw,freezer
  1. 第四个字段 ( /..) 显示了在 cgroup 文件系统中的挂载目录。从 cgroup namespaces 的定义中,我们可以知道,进程当前的 freezer cgroup 目录变成了它的根目录,所以这个字段显示 /.. 。我们可以重新挂载来处理它。
root@moelove:~# mount --make-rslave /
root@moelove:~# umount /sys/fs/cgroup/freezer
root@moelove:~# mount -t cgroup -o freezer freezer /sys/fs/cgroup/freezer
root@moelove:~# cat /proc/self/mountinfo | grep freezer
1238 1230 0:37 / /sys/fs/cgroup/freezer rw,relatime - cgroup freezer rw,freezer
root@moelove:~# mount |grep freezer
freezer on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer)

IPC namespaces

IPC namespaces 隔离了 IPC 资源,如 System V IPC objects、 POSIX message queues。每个 IPC namespace 都有着自己的一组 System V IPC 标识符,以及 POSIX 消息队列系统。在一个 IPC namespace 中创建的对象,对所有该 namespace 下的成员均可见(对其他 namespace 下的成员均不可见)。

使用 IPC namespace 需要内核支持 CONFIG_IPC_NS 选项。如下:

(MoeLove) ➜ grep CONFIG_IPC_NS /boot/config-$(uname -r)
CONFIG_IPC_NS=y

可以在 IPC namespace 中设置以下 /proc 接口:

  • /proc/sys/fs/mqueue - POSIX 消息队列接口
  • /proc/sys/kernel - System V IPC 接口 (msgmax, msgmnb, msgmni, sem, shmall, shmmax, shmmni, shm_rmid_forced)
  • /proc/sysvipc - System V IPC 接口

当 IPC namespace 被销毁时(空间里的最后一个进程都被停止删除时),在 IPC namespace 中创建的 object 也会被销毁。

Network namespaces

Network namespaces 隔离了与网络相关的系统资源(这里罗列一些):

  • network devices - 网络设备
  • IPv4 and IPv6 protocol stacks - IPv4、IPv6 的协议栈
  • IP routing tables - IP 路由表
  • firewall rules - 防火墙规则
  • /proc/net (即 /proc/PID/net)
  • /sys/class/net
  • /proc/sys/net 目录下的文件
  • 端口、socket
  • UNIX domain abstract socket namespace

使用 Network namespaces 需要内核支持 CONFIG_NET_NS 选项。如下:

(MoeLove) ➜ grep CONFIG_NET_NS /boot/config-$(uname -r)
CONFIG_NET_NS=y

一个物理网络设备只能存在于一个 Network namespace 中。当一个 Network namespace 被释放时(空间里的最后一个进程都被停止删除时),物理网络设备将被移动到初始的 Network namespace 而不是上层的 Network namespace。

一个虚拟的网络设备(veth(4)) ,在 Network namespace 间通过一个类似管道的方式进行连接。这使得它能存在于多个 Network namespace,但是,当 Network namespace 被摧毁时,该空间下包含的 veth(4) 设备可能被破坏。

Mount namespaces

Mount namespaces 最早出现在 Linux 2.4.19 版本。Mount namespaces 隔离了各空间中挂载的进程实例。每个 mount namespace 的实例下的进程会看到不同的目录层次结构。

每个进程在 mount namespace 中的描述可以在下面的文件视图中看到:

  • /proc/[pid]/mounts
  • /proc/[pid]/mountinfo
  • /proc/[pid]/mountstats

一个新的 Mount namespace 的创建标识是 CLONE_NEWNS ,使用了 clone(2) 或者 unshare(2) 。

  • 如果 Mount namespace 用 clone(2) 创建,子 namespace 的挂载列表是从父进程的 mount namespace 拷贝的。
  • 如果 Mount namespace 用 unshare(2) 创建,新 namespace 的挂载列表是从调用者之前的 moun namespace 拷贝的。

如果 mount namespace 发生了修改,会引起什么样的连锁反应?下面,我们就在 共享子树中谈谈。

每个 mount 都被可以有如下标记 :

  • MS_SHARED - 与组内每个成员分享 events 。也就是说相同的 mount 或者 unmount 将自动发生在组内其他的 mounts 中。反之,mount 或者 unmount 事件 也会影响这次的 event 动作。
  • MS_PRIVATE - 这个 mount 是私有的。mount 或者 unmount events 都不会影响这次的 event 动作。
  • MS_SLAVE - mount 或者 unmount events 会从 master 节点传入影响该节点。但是这个节点下的 mount 或者 unmount events 不会影响组内的其他节点。
  • MS_UNBINDABLE - 这也是个私有的 mount 。任何尝试绑定的 mount 在这个设置下都将失败。

在文件 /proc/[pid]/mountinfo 中可以看到 propagation 类型的字段。每个对等组都会由内核生成唯一的 ID ,同一对等组的 mount 都是这个 ID(即,下文中的 X )。

(MoeLove) ➜ cat /proc/self/mountinfo  |grep root  
65 1 0:33 /root / rw,relatime shared:1 - btrfs /dev/nvme0n1p6 rw,seclabel,compress=zstd:1,ssd,space_cache,subvolid=256,subvol=/root
1210 65 0:33 /root/var/lib/docker/btrfs /var/lib/docker/btrfs rw,relatime shared:1 - btrfs /dev/nvme0n1p6 rw,seclabel,compress=zstd:1,ssd,space_cache,subvolid=256,subvol=/root
  • shared:X - 在组 X 中共享。
  • master:X - 对于组 X 而言是 slave,即,从属于 ID 为 X 的主。
  • propagate_from:X - 接收从组 X 发出的共享 mount。这个标签总是个 master:X 一同出现。
  • unbindable - 表示不能被绑定,即,不与其他关联从属。

新 mount namespace 的传播类型取决于它的父节点。如果父节点的传播类型是 MS_SHARED ,那么新 mount namespace 的传播类型是 MS_SHARED ,不然会默认为 MS_PRIVATE。

关于 mount namespaces 我们还需要注意以下几点:

(1)每个 mount namespace 都有一个 owner user namespace。如果新的 mount namespace 和拷贝的 mount namespace 分属于不同的 user namespace ,那么,新的 mount namespace 优先级低。

(2)当创建的 mount namespace 优先级低时,那么,slave 的 mount events 会优先于 shared 的 mount events。

(3)高优先级和低优先级的 mount namespace 有关联被锁定在一起时,他们都不能被单独卸载。

(4)mount(2) 标识和 atime 标识会被锁定,即,不能被传播影响而修改。

cgroup 相关参考网友文档

https://zhuanlan.zhihu.com/p/434731896

日志清理

清理5天前日志

find ./* -mtime +5 -name "*.log.gz" -exec rm -f {} \;

查找当前目录下所有以.tar结尾的文件然后移动到指定目录:
find ./ -name "*.tar" -exec mv {} ./backup;

查找当前目录30天以前大于100M的LOG文件并删除:
find ./ -name "*.log" -mtime +30 -type f -size +100M|xargs rm -rf {};

清理容器日志
cat /data/scripts/clean_docker_log.sh
truncate -s 0 /var/lib/docker/containers/*/*-json.log

image-20231102190225684

TCP/IP协议栈

三次握手

https://www.cnblogs.com/dbhui/p/9596465.html

image-20231102190429487

image-20231102190452559

(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

SYN攻击: 在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:

#netstat -nap | grep SYN_RECV

四层握手的几种状态

待补充

11种状态
prometheus中都有metrics监控,可以根据情况进行监控
LISTEN:等待从任何远端 TCP 和端口的连接请求
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态
FIN_WAIT_1:等待远端 TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认
FIN_WAIT_2:等待远端 TCP 的连接终止请求
CLOSE_WAIT:等待本地用户的连接终止请求
CLOSING:等待远端 TCP 的连接终止请求确认
LAST_ACK:等待先前发送给远端 TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端 TCP 接收到它的连接终止请求的确认
TIME_WAIT 两个存在的理由:
1.可靠的实现 TCP 全双工连接的终止
2.允许老的重复分节在网络中消逝

CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)

mysql相关

一、MySQL5.6.16版本的主从复制搭建: 主机A IP:192.168.233.131 主机B IP:192.168.233.132 1)修改mysql的配置文件:

(1)开启二进制日志功能
(2)server-id = 1 //另外一台设置为2

2)在slave数据库上添加授权复制用户,在master数据库上进行授权:

create user 'repl'@'192.168.1.%' identified by 'your-password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
flush privileges;

3)在master数据库上执行show master status;命令:(查看)

mysql> show master status\G;
*************************** 1. row ***************************
File: mysql-master-bin.000005
Position: 120
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
4)在slave数据库上执行:
mysql> change master to master_host='192.168.233.131', master_user='repl',master_password='your-password',master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.24 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.04 sec)
5)在slave上执行`show slave status;`查看slave的状态:如果下面这俩个文件都为YES,则表示mysql主从复制搭建成功:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

二、mysql 主从不一致解决方法 方法一:忽略错误,同步 该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况 解决:

stop slave;
#表示跳过一步错误,后面的数字可变
set global sql_slave_skip_counter =1;
start slave;
之后再用mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
ok,现在主从同步状态正常了

主从复制原理

主从复制是MySQL提供的基本的技术,主从复制的流程:binlog二进制日志(除了查询其他的更改相关的操作都会记录在binlog里面)、relay log日志和三个线程(master的一个线程和slave的两个线程)

主从复制的好处:数据备份,我们甚至可以给它做一个热备份,就是通过MySQL中间件mycat,可以实现容灾,容灾也体现了高可用。


主从复制的流程:
两个日志(binlog二进制日志和relay log日志)和三个线程(master的一个线程和slave的两个线程)。

主库的更新操作写入binlog二进制日志中(主库需要打开binlog开关)

master服务器创建一个binlog转储线程,将二进制日志内容发送到从服务器

slave机器执行START SLAVE命令会在从服务器创建一个IO线程,接收master的binary log复制到其中继日志(处于内存中,读写快)。 首先slave开始一个工作线程(I/O线程),I/O线程会主动连接master ,然后主库会开启dump线程,dump线程从master的binlog中读取事件并发送给slave的I/O线程,如果dump线程已经跟上master(主库上的dump线程已经把binlog的内容发完了,而且主库上binlog没有产生更多的内容),dump线程会睡眠并等待binlog产生新的事件,slave的I/O线程接收的事件写入中继日志

slave的SQL线程处理该过程的最后一步,SQL线程从relay log中读取事件,并执行其中的事件更新slave的数据,使其与master的数据同步。只要SQL线程与I/O线程保持一致,中继日志通常会位于os缓存中,所以中继日志的开销很小

image-20240508010949153

安全审计

分析业务需求和数据分类

  • 与业务部门合作,了解哪些数据是敏感的,需要加密和保护。分类数据,以便知道如何处

  • 参与安全审计和漏洞扫描,以发现和纠正潜在的安全问题

  • 紧急响应:

    • 协助建立紧急响应计划,以应对数据泄露或其他安全事件
  • 部署加密系统:

    • 协助信息安全团队部署加密系统,确保其正确运行。
    • 监控加密系统的性能和安全性,及时发现并应对潜在的问题。

nginx

请解释Nginx服务器上的Master和Worker进程分别是什么?

Master进程:读取及评估配置和维持

Worker进程:处理请求

mirror

实现简单流量复制

location / {                        # location /指定了源uri为/,也可以定义为其他指定接口
mirror /mirrorone; # mirror /mirror指定镜像uri为/mirror
mirror /mirrortwo; # 有多个需要复制流量的,可以配置多条
mirror /mirrortwo; # 配置多条情况下,将会起到流量放大的作用,即主配置请求一次,镜像端会有两次
# mirror_request_body on; # 指定是否镜像请求body部分,请求自动缓存;
proxy_pass http://backend; # 指定处理主流量的后端Server
}
location = /mirrorone {
internal; # 指定此location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)
proxy_pass http://test_backend1$request_uri; # 指定将要复制流量的Server1
}
location = /mirrortwo {
internal;
proxy_pass http://test_backend2$request_uri;
}

https://cloud.tencent.com/developer/article/1842884

rewrite

rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。 比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

rewrite只能放在server,location,if中,并且默认只能对域名后边的除去传递的参数外的字符串起作用

例如:http://www.kgc.com/abc/[bbs](https://so.csdn.net/so/search?q=bbs&spm=1001.2101.3001.7020)/index.php?a=1&b=2 只对/abc/bbs/index.php重写

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/SmileLife_/article/details/125014507

location

1location大致分为三类

精准匹配:location = / {...}
一般匹配:location / {...}
正则匹配:location ~ / {...}

2 location 常用的匹配规则

= :进行普通字符精确匹配,也就是完全匹配。
^~ :表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其它 location。
~ :区分大小写的匹配。
~* :不区分大小写的匹配。
!~ :区分大小写的匹配取非。
!~* :不区分大小写的匹配取非。

3 location的优先级

相同类型的表达式,字符串长的会优先匹配

首先精确匹配 =
其次前缀匹配 ^~
其次是按文件中顺序的正则匹配 ~或~*
然后匹配不带任何修饰的前缀匹配
最后是交给 / 通用匹配

4 location 匹配

首先看 优先级:精确>前缀>正则>一般>通用
优先级相同:正则看上下顺序,上面的优先;一般匹配看长度,最长匹配的优先
精确、前缀、正则、一般 都没有匹配到,最后再看通用匹配

5 实际网站使用中,至少有三个匹配规则定义

1、第一个必选规则

  • 直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
  • 可以是一个静态首页,也可以直接转发给后端应用服务器
location = / {
root html;
index index.html index.htm;
}

2、第二个必选规则

处理静态文件请求,这是nginx作为http服务器的强项;有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {
root /webroot/static/;
}

location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}

3、第三个必选规则

就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器非静态文件请求就默认是动态请求

location / {
proxy_pass http://tomcat_server;
}

二、rewrite实例

1、基于域名的跳转

2、基于客户端 IP 访问跳转

3、 基于旧域名跳转到新域名后面加目录

4、基于参数匹配的跳转

5、基于目录下所有 php 结尾的文件跳转

6、基于最普通一条 url 请求的跳转

比较rewrite和location

1、相同点:都能实现跳转

2、不同点:

①、rewrite是在同一域名内更改获取资源的路径

②、location是对一类路径控制访问或反向代理,还可以proxy_pass到其他机器

3、rewrite会写在location里,执行顺序

①、执行server块里面的rewrite指令

②、执行location匹配

③、执行选定的location中的rewrite指令

localtion优先级

匹配某个具体文件
(location = 完整路径)>(location ^~ 完整路径)>(location ~* 完整路径)=(location ~ 完整路径)>(location /)

用目录做匹配访问某个文件
(location = 目录)>(location ^~ 目录)>(location ~* 目录)=(location ~ 目录)>(location /)

nginx限流

两个命令

限流由两个主要指令limit_req_zone和进行配置limit_req,如下例所示:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

server {
location /qhyu/ {
limit_req zone=mylimit;

proxy_pass http://my_upstream;
}
}
limit_req_zone指令定义了速率限制的参数,zone-请求限制URL的频率的共享内存区域,rate-设置最大请求速率
limit_req在它出现的上下文中启用速率限制,速率不能超过每秒10个请求

nginx七层代理

只能写在http模块的全局配置当中。 upstream: 用于处理http请求,支持反向代理,负载均衡,缓存功能 在upstream模块中可以配置对个服务器

upstream liu {
server 192.168.10.30;
server 192.168.10.20;
}
location {
proxy_pass http://test;
}

nginx四层代理

stream只能写在全局模块当中的单独配置。stream代理无谓协议,只管流量。

stream {
upstream ilync{
server 192.168.10.20:8080;
server 192.168.10.21:8080;
}
server {
listen 80;
proxy_pass ilync;
}

}
不能用 hash(哈希),只可以使用weight 和 least_conn。

基于域名的反向代理

upstream ky32 (
server www.kgc.com;
server www.benet.com;
}

location {
proxy_pass http://ky32
proxy_set_header HoST $host
#把请求的主机名发送给后端
proxy_set header X-Real-IP $remote_addr;
#后端服务器获取客户端的真实ip地址。
}

正向代理和反向代理

代理对象不同。正向代理代理的是客户端(比如qq通过代理实现上网,服务器端通过socket5来实现代理),反向代理代理的是服务器。

正向代理帮助客户访问其无法访问的服务器资源,反向代理帮助服务器做负载均衡,另外,由于客户端跟真实服务器不直接接触,能起到一定安全防护的作用。

架设主体不同。正向代理一般是客户端架设的,比如在自己的机器上装一个代理软件,反向代理一般是服务器架设的,通常是在机器集群中部署个反向代理服务器