### 在linux中，什么是用户态、内核态

```
一、内核态、用户态概念
内核态：也叫内核空间，是内核进程/线程所在的区域。主要负责运行系统、硬件交互。
用户态：也叫用户空间，是用户进程/线程所在的区域。主要用于执行用户程序。
二、内核态和用户态的区别
内核态：运行的代码不受任何限制，CPU可以执行任何指令。
用户态：运行的代码需要受到CPU的很多检查，不能直接访问内核数据和程序，也就是说不可以像内核态线程一样访问任何有效地址。
操作系统在执行用户程序时，主要工作在用户态，只有在其执行没有权限完成的任务时才会切换到内核态。
三、为什么要区分内核态和用户态
保护机制。防止用户进程误操作或者是恶意破坏系统。内核态类似于C++的私有成员，只能在类内访问，用户态类似于公有成员，可以随意访问。
四、用户态切换到内核态的方式
1、系统调用（主动）
由于用户态无法完成某些任务，用户态会请求切换到内核态，内核态通过为用户专门开放的中断完成切换。
2、异常（被动）
执行用户程序时出现某些不可知的异常，会从用户程序切换到内核中处理该异常的程序，也就是切换到了内核态。
```

### tcp和udp区别

```
连接导向 vs 无连接：TCP是面向连接的协议，它在发送和接收数据之前需要建立连接。而UDP是无连接的协议，它不需要建立连接，可以直接发送数据。

可靠性：TCP提供可靠的数据传输，它使用确认和重传机制来确保数据的可靠性。而UDP不提供可靠性，它只是简单地发送数据，不保证数据的传输和接收。

顺序性：TCP保证数据的顺序性，它会按照发送顺序对数据进行排序。而UDP不保证数据的顺序性，接收方可能会以不同的顺序接收到数据。

拥塞控制：TCP具有拥塞控制机制，它会根据网络的拥塞情况动态调整发送数据的速率。而UDP没有拥塞控制，会以恒定的速率发送数据。

数据量限制：TCP没有固定的数据量限制，可以传输任意大小的数据。而UDP有数据报的大小限制，每个数据报的最大长度为64KB。

延迟：TCP的延迟较高，因为它需要建立连接和进行确认。而UDP的延迟较低，因为它不需要建立连接和进行确认。
```

### nginx和lvs区别，各自优缺点

```
功能：Nginx是一种高性能的Web服务器和反向代理服务器，它可以通过反向代理实现基本的负载均衡功能。LVS是一种专门的负载均衡解决方案，它可以实现更复杂的负载均衡算法和功能。
负载均衡算法：Nginx支持的负载均衡算法有轮询、IP哈希、最小连接等。LVS支持的负载均衡算法更多，包括轮询、加权轮询、源IP哈希、最少连接等。
部署方式：Nginx可以在单个服务器上部署，通过多个Nginx实例实现负载均衡。LVS是一种集群技术，需要多台服务器组成集群来实现负载均衡。
可扩展性：Nginx在水平扩展方面较为简单，可以通过添加更多的Nginx实例来增加负载均衡能力。LVS在可扩展性方面更强大，可以通过添加更多的服务器节点来扩展负载均衡集群。
性能：Nginx具有出色的性能和高并发处理能力，适用于处理大量的静态请求。LVS也具有很高的性能，适用于处理大量的动态请求和长连接。
配置和管理：Nginx的配置相对简单，易于理解和管理。LVS的配置相对复杂，需要更多的配置和管理工作。
总体而言，Nginx适用于简单的负载均衡需求，具有简单的配置和高性能。LVS适用于复杂的负载均衡需求，具有更多的负载均衡算法和可扩展性。选择使用哪种技术取决于具体的需求和环境。
```

### Keeplive的工作原理如下：

```
1. 客户端和服务器建立网络连接。
2. 客户端和服务器之间的数据传输完毕后，如果没有其他数据需要传输，连接将保持空闲。
3. 客户端和服务器会定期交换Keeplive数据包，以保持连接活跃。
4. 如果一方在一段时间内没有收到对方的Keeplive数据包，它会假设连接已经断开，并尝试重新建立连接。
```

### iptables原理

```
数据包到达Linux系统后，首先经过网络接口的预处理阶段（PREROUTING）。
在预处理阶段，数据包会经过iptables的规则链（rules chain）。
规则链是一系列规则的集合，每个规则包含一些匹配条件和对应的操作动作。
数据包会按照规则链中的顺序逐一匹配规则，直到找到匹配的规则或到达链的末尾。
如果数据包匹配成功，将执行规则中指定的操作动作，如丢弃、接受、修改等。
如果数据包没有匹配任何规则，将按照默认策略进行处理，如丢弃或接受。
如果数据包通过了预处理阶段，将进入本地处理阶段（INPUT）或转发处理阶段（FORWARD）。
在本地处理阶段或转发处理阶段，数据包将再次经过规则链的匹配和操作过程。
最后，数据包将进入出口处理阶段（OUTPUT），并根据规则链中的规则进行处理。
处理完成后，数据包将离开Linux系统，进入网络中的下一跳。
```

### cpu过高，如何排查

```
使用系统监控工具：使用 top、htop、sar 等工具查看当前 CPU 使用率最高的进程或线程。观察其 CPU 使用率、内存占用等信息，确定是哪个进程导致的 CPU 过高。
检查系统负载：使用 uptime 或者 w 命令查看系统负载情况。如果系统负载过高（负载平均值超过 CPU 核心数），可能是因为有大量进程在竞争 CPU 资源。
检查进程资源占用：使用 ps 命令查看 CPU 占用率最高的进程的详细信息，包括进程的 PID、CPU 使用率、内存占用等。可以使用 top 或 htop 命令实时监控进程的资源占用情况。
检查进程调度策略：使用 taskset、chrt 等命令查看进程的调度策略和优先级。如果进程的调度策略设置不合理，可能导致 CPU 过高。

检查进程日志：查看进程的日志文件，检查是否有异常报错信息。有时候 CPU 过高可能是由于进程出现了异常或错误。
检查系统资源使用情况：使用 free、df、iostat 等命令查看系统的内存、磁盘、网络等资源的使用情况。如果系统资源不足，可能导致 CPU 过高。
检查定时任务和后台服务：查看系统中是否有定时任务或后台服务导致 CPU 过高。可以使用 crontab -l 命令查看定时任务，使用 systemctl status <service> 命令查看后台服务状态。
```

### 固定配置机器，如何提高并发

```
多线程/多进程：使用多线程或多进程的方式，将任务分发给多个线程或进程同时执行，从而提高并发处理能力。注意要合理控制线程/进程的数量，避免过多的线程/进程导致资源竞争和上下文切换开销增加。
异步编程：使用异步编程模型，例如使用异步IO、回调函数、事件驱动等方式，可以在等待IO操作时释放CPU资源，提高并发处理能力。常见的异步编程框架包括 asyncio（Python）、Netty（Java）、Node.js（JavaScript）等。
连接池和线程池：对于需要频繁连接数据库、HTTP请求等场景，可以使用连接池和线程池来管理连接和线程资源，避免频繁的连接和线程创建销毁开销，提高并发处理能力。
缓存：对于频繁读取的数据，可以使用缓存技术（如 Redis、Memcached）将数据缓存在内存中，减少对数据库等后端存储的访问，提高并发处理能力。
负载均衡：使用负载均衡技术将请求分发到多台机器上，通过横向扩展机器数量来提高并发处理能力。常见的负载均衡技术包括 Nginx、HAProxy、LVS 等。
数据库优化：对于涉及数据库操作的应用，可以通过优化数据库查询语句、建立合适的索引、调整数据库连接池等方式来提高数据库的并发处理能力。
系统调优：对操作系统进行调优，例如调整内核参数、优化网络配置等，可以提高系统的并发处理能力。

垂直扩展和水平扩展：对于需要处理大量并发请求的场景，可以通过垂直扩展（增加单个机器的硬件资源）或水平扩展（增加机器数量）来提高并发处理能力。
```

### top中常见的值及含义，如ns等

```
PID：进程 ID。
USER：进程所属的用户。
PR：进程的优先级。
NI：进程的 nice 值，用于调整进程的优先级。
VIRT：进程使用的虚拟内存大小。
RES：进程使用的物理内存大小。
SHR：进程共享的内存大小。
S：进程的状态，常见的状态有 R（运行）、S（睡眠）、D（不可中断的睡眠）、Z（僵尸）等。
%CPU：进程的 CPU 使用率。
%MEM：进程的内存使用率。
TIME+：进程已经运行的 CPU 时间。
COMMAND：进程的命令名称。
```

### 怎么查看当前CPU使用率具体的哪个字段？还有就是内存使用率具体哪个字段？

```
top命令
CPU 使用率相关字段：
%Cpu(s)：显示整个系统的 CPU 使用率。
us：用户空间进程所占用的 CPU 时间百分比。
sy：内核空间进程所占用的 CPU 时间百分比。
ni：以较低优先级运行的用户空间进程所占用的 CPU 时间百分比。
id：空闲 CPU 时间百分比。
wa：等待 I/O 完成的 CPU 时间百分比。
hi：硬中断（Hardware Interrupts）所占用的 CPU 时间百分比。
si：软中断（Software Interrupts）所占用的 CPU 时间百分比。

内存使用率相关字段：
KiB Mem：物理内存总量。
used：已使用的物理内存量。
free：空闲的物理内存量。
buff/cache：被用作缓冲区和缓存的内存量。
available：可用的物理内存量。
%MEM：进程使用的物理内存百分比。
```

### 域名解析，怎么配置的DNS，里边具体配置过程

```
打开 DNS 配置文件：
在大多数 Linux 发行版中，DNS 配置文件位于 /etc/resolv.conf
编辑 DNS 配置文件：
在文件中，您会看到一行以 nameserver 开头的条目，后面跟着 IP 地址。这些 IP 地址指定了 DNS 服务器。

添加或修改 DNS 服务器：
如果您需要添加新的 DNS 服务器，请在文件中添加一行以 nameserver 开头的条目，后面跟着新的 DNS 服务器的 IP 地址。例如：nameserver 8.8.8.8。
如果您需要修改现有的 DNS 服务器，请找到相应的 nameserver 条目，并将其 IP 地址更改为新的 DNS 服务器的 IP 地址。
保存并关闭文件。
测试 DNS 配置：

在终端或命令提示符中，使用 ping 命令测试域名解析是否正常。例如：ping example.com。如果域名能够解析为 IP 地址并成功响应，则说明 DNS 配置生效
```

### 远程登录主机，然后具体怎么配置的加密

```
/etc/ssh/sshd_config
禁用不安全的验证方法：确保以下配置项处于启用状态：
PasswordAuthentication no
ChallengeResponseAuthentication no

启用公钥验证：确保以下配置项处于启用状态
PubkeyAuthentication yes

限制登录用户：通过 AllowUsers 或 AllowGroups 配置项，只允许特定的用户或用户组进行远程登录。
修改 SSH 服务器的监听端口（可选）：通过 Port 配置项，将 SSH 服务器的监听端口更改为非默认端口（默认为 22）。

```

### 两台主机ping之后如果ping不通还有什么原因导致的，并且经过哪些路由怎么查看？

```
防火墙阻止了    防火墙阻止了   网络硬件故障：网络硬件（如交换机、路由器、网卡等
路由问题：
在 Linux 上，使用 traceroute 命令来跟踪到达目标主机的网络路径。例如：traceroute <目标主机 IP>。
```

### 7层协议，4层协议，表面几层里边有啥东西

```
物理层（Physical Layer）：负责在物理媒介上传输原始比特流。
数据链路层（Data Link Layer）：负责对物理层传输的比特流进行分帧、错误检测和纠正等处理。
网络层（Network Layer）：负责将数据包从源主机传输到目标主机，包括寻址、路由选择和流量控制等功能。
传输层（Transport Layer）：负责端到端的数据传输，提供可靠的数据传输和流量控制等功能。
会话层（Session Layer）：负责管理和建立会话连接，以及在通信双方之间建立和维护通信会话。
表示层（Presentation Layer）：负责数据的格式化、加密和压缩等操作，以确保不同系统之间的数据能够正确解释和交换。
应用层（Application Layer）：负责处理特定的网络应用程序，例如 HTTP、FTP、DNS 等协议。
在 TCP/IP 四层模型中，将 OSI 模型中的会话层、表示层和应用层合并为应用层，因此有以下层级：

网络接口层（Network Interface Layer）：负责将数据传输到物理媒介上，处理与网络硬件的交互。
网络层（Internet Layer）：负责网络互连和数据包的路由选择和转发。
传输层（Transport Layer）：提供端到端的数据传输服务，包括可靠的数据传输和流量控制。
应用层（Application Layer）：负责处理特定的网络应用程序，例如 HTTP、FTP、DNS 等协议。
```

### zabbix怎么做过自定义监控

```
创建自定义监控项（Item）：

登录到 Zabbix 管理界面。
转到 "配置" 菜单，选择 "主机"。
选择要添加自定义监控项的主机。
在 "监控项" 选项卡中，点击 "创建监控项"。
在 "监控项" 页面，填写监控项的名称、键值（唯一标识符）和其他相关信息。
选择合适的监控项类型，例如 Zabbix Agent、SNMP、JMX 等。
配置监控项的参数，例如间隔时间、阈值等。
保存监控项配置。
创建自定义触发器（Trigger）：

在 "配置" 菜单中，选择 "触发器"。
点击 "创建触发器"。
在 "触发器" 页面，填写触发器的名称和表达式。
根据需要，设置触发器的优先级、依赖关系等。
保存触发器配置。
创建自定义图表（Graph）：

在 "配置" 菜单中，选择 "图形"。
点击 "创建图形"。
在 "图形" 页面，填写图形的名称和相关信息。
添加之前创建的自定义监控项到图形中。
配置图形的显示选项，例如时间范围、刷新间隔等。
保存图形配置。
创建自定义报警动作（Action）：

在 "配置" 菜单中，选择 "报警动作"。
点击 "创建动作"。
在 "动作" 页面，填写动作的名称和相关信息。
配置报警条件和操作，例如触发器状态、报警通知方式等。
保存报警动作配置。
通过以上步骤，您可以在 Zabbix 中创建自定义的监控项，设置触发器进行报警，创建图表进行数据可视化，并配置报警动作进行通知。这样就可以实现自定义的监控需求。
```

### zabbix监控被动模式和主动模式，应用什么场景

```
被动模式：
被动模式是指被监控主机主动向 Zabbix 服务器发送数据。
在被动模式下，被监控主机上安装的 Zabbix Agent 定期连接到 Zabbix 服务器，并发送数据。
这种模式适用于监控主机数量较少、主机 IP 地址变化频繁或者主机位于防火墙后的情况。
被动模式需要在被监控主机上安装和配置 Zabbix Agent。

主动模式：
主动模式是指 Zabbix 服务器主动连接到被监控主机，并请求数据。
在主动模式下，被监控主机上安装的 Zabbix Agent 监听指定端口，等待 Zabbix 服务器的连接。
这种模式适用于监控主机数量较多、主机 IP 地址变化较少的情况。
主动模式需要在被监控主机上安装和配置 Zabbix Agent，并在防火墙中允许 Zabbix 服务器连接。
根据具体的监控需求和网络环境，可以选择被动模式或主动模式。如果主机数量较少或者主机 IP 地址变化频繁，可以选择被动模式。如果主机数量较多或者主机 IP 地址变化较少，可以选择主动模式。另外，被动模式和主动模式也可以结合使用，根据实际情况进行灵活配置。
```

### 多个IP怎么测试这个连通性

```
telnet 或者ping   +脚本

#!/bin/bash

# 定义文件路径
file_path="ip_addresses.txt"

# 读取文件内容，提取 IP 地址并测试连通性
while IFS= read -r line
do
  # 使用正则表达式提取 IP 地址
  ip=$(echo "$line" | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b") 
  # 测试连通性
  ping -c 1 "$ip" > /dev/null
  # 判断返回值，输出结果
  if [ $? -eq 0 ]; then
    echo "$ip is reachable"
  else
    echo "$ip is not reachable"
  fi
done < "$file_path"
```

怎么查看一个文件的创建时间和修改时间^

```
stat
ls -l
```

elk和efk的区别是什么? 为什么f比L更加轻量级

```
ELK 和 EFK 是两种常用的日志分析平台，它们之间的区别在于使用的日志收集工具。

ELK 是由 Elasticsearch、Logstash 和 Kibana 组成的日志分析平台。其中，Logstash 用于日志的收集、过滤和转发，Elasticsearch 用于存储和索引日志数据，Kibana 用于可视化和查询日志数据。

EFK 是由 Elasticsearch、Fluentd 和 Kibana 组成的日志分析平台。其中，Fluentd 用于日志的收集、过滤和转发，Elasticsearch 用于存储和索引日志数据，Kibana 用于可视化和查询日志数据。

主要区别在于 Logstash 和 Fluentd 这两个组件。Logstash 是用 Java 编写的，而 Fluentd 是用 Ruby 编写的。相对而言，Ruby 是一种更轻量级的语言，因此 Fluentd 在资源消耗方面可能更低，更适合一些资源有限的环境。

此外，Fluentd 还具有一些其他特点，如可插拔的输出插件和更广泛的社区支持。这使得 Fluentd 在一些场景下更受欢迎，特别是在容器化和云原生应用中。

需要注意的是，ELK 和 EFK 只是日志分析平台的一种常见组合，实际上还可以根据需求和偏好选择其他组件来构建日志分析平台。
```

### .filebeat是怎么过滤的

```
在Filebeat中，过滤可以通过两个主要组件来实现：输入（input）和处理（processor）。

输入（input）：输入是指指定要监视的日志文件或者文件夹。Filebeat支持多种类型的输入，如文件输入（File Input）、日志文件输入（Log File Input）、容器日志输入（Docker Input）等。你可以根据你的需求选择适当的输入类型，并指定要监视的文件路径或者文件夹路径。

处理（processor）：处理是指对输入的数据进行过滤或者转换操作。Filebeat提供了一系列的处理器，用于处理日志数据。例如，你可以使用drop_fields处理器来删除不需要的字段，使用include_lines处理器来仅包括指定的行，使用decode_json_fields处理器来解析JSON格式的日志字段等。通过配置处理器链，你可以按照特定的逻辑对日志数据进行处理和过滤。
filebeat.inputs:
- type: log
  paths:
    - /path/to/log/file.log

processors:
- drop_fields:
    fields: ["field1", "field2"]

output.elasticsearch:
  hosts: ["localhost:9200"]
```

### nginx让它域名访问的

```
配置域名解析：将域名解析到指向Nginx服务器的IP地址。这可以通过在域名注册商处设置DNS记录来完成。在DNS记录中添加一个A记录，将域名指向Nginx服务器的IP地址
然后配置文件
server {
    listen 80;
    server_name your_domain.com;
    ...
}
检查防火墙设置
```

### 访问不到出现什么问题?

```
看nginx日志
域名解析问题，防火墙问题
nginx配置问题，nginx -t
```

### k8s的pod类型

```
在 Kubernetes 中，有几种不同类型的 Pod，可以根据需求选择适合的类型。以下是一些常见的 Pod 类型：

ReplicaSet：ReplicaSet 是一种管理 Pod 副本数的控制器，确保在任何时候都有指定数量的 Pod 实例在运行。它可以自动进行水平扩展和缩减。ReplicaSet 通常与 Deployment 一起使用。

Deployment（滴泼们）：Deployment 是一个更高级别的抽象，它包装了 ReplicaSet，并提供了更多的功能，如无中断滚动更新、版本回滚和滚动部署等。Deployment 是最常用的 Pod 管理工具之一。

StatefulSet（斯跌佛set）：StatefulSet 用于管理有状态应用的 Pod。它为每个 Pod 实例分配一个唯一的网络标识符（如稳定的网络主机名和持久卷声明），确保每个实例具有唯一的标识和稳定的存储。

DaemonSet(低闷set)：DaemonSet 用于在 Kubernetes 集群中的每个节点上运行一个 Pod 的副本。它确保所有节点都运行相同的 Pod。

Job 和 CronJob：Job 用于运行一次性的任务，而 CronJob 用于定期运行任务。它们创建一个或多个 Pod 完成任务，并在任务完成后自动终止。

EmptyDir Pod(an低爹儿)：EmptyDir Pod 使用临时存储卷，数据只在 Pod 的生命周期内有效。当 Pod 终止时，存储卷中的数据将被清除。

Sidecar Pod(赛car)：Sidecar Pod 在同一 Pod 中运行与主要应用程序容器共享相同的生命周期的辅助容器。Sidecar 容器通常用于日志收集、监控、数据转换等任务。
```

### deployment怎么写的

```
apiVersion: 指定 Kubernetes API 的版本。对于 Deployment，使用 apps/v1。
kind: 指定对象的类型，对于 Deployment 来说是 Deployment。
metadata: 用于定义 Deployment 对象的元数据，如名称、标签等。
spec: 定义 Deployment 的规格，包括以下重要的设置：
replicas: 指定要创建的 Pod 的副本数。
selector: 定义用于选择要进行管理的 Pod 的标签选择器。
template: 定义要创建的 Pod 的模板。包括以下部分：
metadata: 定义要创建的 Pod 的元数据，如标签。
spec: 定义要创建的 Pod 的规格，包括以下内容：
containers: 定义 Pod 中运行的容器列表。每个容器包括以下设置：
name: 定义容器的名称。
image: 定义容器使用的镜像。
ports: 定义容器要打开的端口。
等等，根据需求可以添加其他容器相关的设置。
```

### k8s滚动更新

```
滚动更新是 Kubernetes 中的一种常见部署策略，它可以实现在不中断应用程序的情况下逐步更新应用程序的副本。
滚动更新配置部分定义在 Deployment 的 spec.strategy 下方。
type: RollingUpdate：指定使用滚动更新策略。
通过在滚动更新策略中设置的最大不可用和最大增长数量，可以控制更新过程的流畅性和可用性
```

### pod只更新50%，怎么更新

```
首先，使用 kubectl get deployment <deployment-name> 命令获取当前的 Deployment 配置和状态。请将 <deployment-name> 替换为你要更新的 Deployment 名称。

根据获取到的 Deployment 配置，计算出当前 Pod 的总副本数。假设总副本数为 N。

计算需要更新的 Pod 数量。将总副本数除以 2，向上取整，得到 N/2。

使用 kubectl scale deployment <deployment-name> --replicas=<N/2> 命令将 Deployment 的副本数缩减为所需更新数量。

例如，如果总副本数为 10，需要更新一半的 Pod，那么 N/2 就是 10/2 = 5。命令将是 kubectl scale deployment my-deployment --replicas=5，其中 my-deployment 是你的 Deployment 名称。

Kubernetes 将自动开始滚动更新过程，逐步替换旧版本的 Pod。你可以使用 kubectl get pods 命令来查看更新的进度和状态。
```

