⚡ 小马运维知识库
星空为幕 · 海浪为伴 · 雷鸣为钟 — 记录每一个运维知识点
单位计算:b 比特 8b=1B
- B 字节 1000B=1KB
- KB 1000KB-1MB
- MB 1000MB=1GB
- GB
虚拟机生命周期:创建→开机运行→暂停 / 挂起→关机→快照 / 克隆 / 改配置→销毁删除
SMTP/IMAP 服务授权码:fiskcwibafavieah
SMTP/IMAP 服务授权码:fiskcwibafavieah
刷题的两个网站
刷题的两个网站
- 牛客网
- leetcode
- gitee
C:\Windows\System32\drivers\etc\host 本地host文件目录
HTTP 常见状态码
HTTP 常见状态码
- 1xx 信息性(接收请求,继续处理)
- 100 继续:客户端继续发送请求
- 2xx 成功(请求正常处理)
- 200 OK:请求成功,正常返回数据
- 201 Created:资源创建成功(POST 新建资源)
- 204 No Content:成功无返回内容(删除常用)
- 3xx 重定向(需要跳转)
- 301 永久重定向:资源永久迁移,浏览器缓存跳转
- 302 临时重定向:资源暂时迁移,下次仍请求原地址
- 304 协商缓存:资源未修改,直接用本地缓存,不返回新数据
- 4xx 客户端错误(请求有问题)
- 400 Bad Request:请求参数 / 格式错误
- 401 Unauthorized:未认证、未登录
- 403 Forbidden:已登录,但无权限访问
- 404 Not Found:请求资源不存在
- 405 Method Not Allowed:请求方式不支持(如接口只支持 GET,你用 POST)
- 409 Conflict:资源冲突(重复创建)
- 5xx 服务端错误(服务器挂了 / 代码报错)
- 500 Internal Server Error:服务器内部代码异常
- 502 Bad Gateway:网关错误,后端服务挂了 / 没起来
- 503 Service Unavailable:服务不可用、过载、维护中
- 504 Gateway Timeout:网关超时,后端响应太慢
三大基础存储形态
- 块存储(Block Storage)
- 把数据切分成固定大小的数据块(类似硬盘分区),带独立编号,直接给服务器当「虚拟硬盘」用
- 读写速度快、延迟低,支持格式化、挂载
- 适合频繁读写、数据库、系统盘
- 举例:云硬盘、SAN 存储、本地硬盘、Ceph RBD
- 文件存储(File Storage)
- 标准文件夹 + 目录树结构,和电脑文件夹一模一样,多台设备可共享访问
- 直接用路径访问(/usr/file),无需格式化
- 适合文档共享、日志存储、网站静态文件
- 举例:NAS、NFS、FTP、Ceph FS
- 对象存储(Object Storage)
- 把文件数据 + 元数据(名称、大小、时间、标签)+ 唯一 ID打包成一个「对象」存储,没有文件夹层级,用唯一 Key/URL 访问
- 扁平化结构,无限扩容,成本极低
- 不支持直接挂载硬盘,适合一次写入、多次读取
- 天然分布式、多副本、防丢失
- 典型场景:图片、视频、备份、静态资源、归档举例:阿里云 OSS、腾讯云 COS、华为 OBS、MinIO、S3
RAID0 / RAID1 / RAID5
- RAID0(条带化)
- 至少2 块盘
- 无冗余、无备份,坏任意一块全盘数据丢失
- 读写速度最快,只追求性能,不适合存重要数据
- RAID1(镜像)
- 至少2 块盘
- 两块盘数据完全一模一样
- 一块坏了不丢数据,安全性高
- 成本高、容量只有总硬盘一半,读写性能一般
- RAID5(分布式奇偶校验)
- 至少3 块盘
- 把校验信息分散存在各盘,允许坏任意 1 块盘不丢数据
- 兼顾性能 + 安全 + 性价比,企业最常用
云计算核心服务模式
- IaaS 基础设施即服务
- 全称:Infrastructure as a Service
- 层级:最底层,硬件资源
- 提供:服务器、硬盘、网络、内存、虚拟机用户
- 负责:系统、中间件、数据库、程序、运维
- 代表:阿里云 ECS、华为云 ECS、VMware
- 特点:自由度最高,自己全权打理
- PaaS 平台即服务
- 全称:Platform as a Service
- 层级:中间开发平台
- 提供:操作系统、运行环境、数据库、开发工具用户
- 负责:只写代码、部署应用
- 代表:阿里云 SAE、腾讯云 TCB、Google App Engine
- 特点:不用管底层环境,专注开发
- SaaS 软件即服务
- 全称:Software as a Service
- 层级:最上层,直接成品软件
- 提供:整套成熟网页 / APP 软件用户
- 负责:只用、登录使用
- 代表:钉钉、企业微信、腾讯文档、网易云课堂
- 特点:开箱即用,零部署
- CaaS 容器即服务
- 全称:Container as a Service
- 核心:基于 Docker 容器交付
- 提供:容器编排、镜像仓库、容器集群介于 IaaS 与 PaaS 之间
- 代表:K8s 集群服务、阿里云容器服务 ACK
- 特点:轻量化、秒级启停、易迁移
- FaaS 函数即服务(无服务器)
- 全称:Function as a Service
- 核心:Serverless 无服务器架构
- 提供:只运行单个函数,不用管服务器 / 容器按调用次数计费
- 代表:阿里云函数计算、腾讯云 SCF
- 特点:极度轻量化,事件触发即用即停
网络传输数据时IP和MAC地址的获得方法
- IP
- 1)通过ipconfig查询IP地址 也就是直接问
- 2)通过DNS域名解析协议获取IP地址
- 3)路由器或服务端有工作人员写的缓存表,用来缓存IP地址
- 4)DHCP地址分发协议获得IP地址
- MAC
一、网络基本概念
网络协议三要素:
- 1.语法:保证发送的数据结构正确,让接收方可以正确接收并且理解其中含义。
- 2.语义:数据本身的意思
- 3.同步:控制数据的收发顺序和速度
网络建设时常见的拓扑结构
- 1.星型拓扑
- 1)主要在接入层、汇聚层时使用
- 2)便于扩展,组建过程简单、易于故障排查、组建成本低
- 3)单节点压力大,可能出现单点出现故障从而影响整个网络环境的情况
- 2.网型拓扑
- 1)主要用于汇聚层、核心层
- 2)具有线路冗余功能,增加网络可靠性
- 3)组建成本高,扩展组建过程繁琐,故障排除较难
网络架构的层级划分
- 1.核心层
- 1)是存储连接内、外网设备的层级,是整个网络环境的核心
- 2)是处理数据量最庞大的区域,压力最大,建议使用高性能设备和线路
- 3)技术以及网络架构层面建议增加冗余性
- 4)主要是由交换机,路由器,防火墙等设备组成
- 2.汇聚层
- 1)连接接入层各个设备,将流量发送到核心层,起到一个承上启下的作用
- 2)按照数量参考是否添加冗余功能
- 3)主要是由网管式交换机组成
- 3.接入层
- 1)连接各个终端设备的交换机
- 2)主要是由非网管交换机(傻瓜式交换机)组成
常见的网络设备
- 1.路由器(route)
- 1)主要是工作在互联网环境下,实现不同网段的互联互通
- 2)是内部网络和外部网络连接的“桥梁”,保证内部网络可以上网
- 3)主要是由IP地址(逻辑地址)寻址
- 4)可以学习MAC地址 但不是主要功能
- 2.交换机(SW——switch)
- 1)主要是工作在局域网环境下,连接各个终端设备使其互联互通
- 2)主要通过MAC地址(物理地址)寻址
- 3.防火墙(firewall)
- 1)主要是在两个网段中心或者内、外网连接点之间工作,保证一个网络向另一个网络传递数据的安全性
- 2)可以通过IP地址寻址,跨网段实现网络转发
二、计算机网络参考模型
分层思想
- 核心目的:把复杂网络传输拆解为功能独立的子过程,复杂问题简单化。
- 核心优势:流程清晰、故障定位精准、便于标准化与独立升级。
- 模型起源:
- ISO 1984 年发布OSI 七层模型(理论标准)。
- 实际应用衍生TCP/IP 五层模型(更贴合互联网)。
OSI 七层模型(自下而上)
- 是由ISO组织定义的OSI七层模型,主要是为了更明确的分析网络数据传递过程
- 从底层到顶层分别是:
- 物理层
- 通过光纤,网线,无线信号等物理介质传递比特流(bit)
- 功能:传输比特流,定义物理接口、电压、介质特性。
- 操作:帧↔电 / 光信号转换。
- 设备 / 介质:网卡、网线、光纤、集线器 (HUB)。
- 数据单位:比特 (bit)。
- 数据链路层
- 通过MAC地址寻址,保证了相邻设备间数据传递的可能性,具有差错检测功能
- 功能:相邻节点可靠通信,帧封装、差错检测 (CRC)、流量控制。
- 操作:加MAC 地址,封装为数据帧。
- 设备:交换机。
- 数据单位:帧 (Frame)(数据帧)。
- 网络层
- 通过IP地址寻址,通过路由表实现不同网络的数据转发
- 功能:跨网络数据包转发,选最优路径。
- 操作:加IP 地址,封装为数据包。
- 设备:路由器。
- 数据单位:包 (Packet)。
- 传输层
- 定义TCP/UDP协议,并且通过上层数据添加对应的端口
- 功能:端到端可靠传输,屏蔽底层差异。
- 操作:加端口号,封装为数据段。
- 核心协议:
- TCP:可靠、面向连接、三次握手 / 四次挥手。
- UDP:不可靠、无连接、实时性高。
- 数据单位:段 (Segment)。
- 会话层
- 建立,维护,终止会话连接
- 功能:建立、管理、终止应用间会话。
- 场景:Web 浏览、Telnet 远程登录。
- 表示层
- 对数据进行压缩、解压缩,加密、解密,编码、解码等操作,并且确认协议中的语法、语义
- 功能:数据格式转换、加密 / 解密、压缩 / 解压缩。
- 示例:HTTPS 加密、编码转换。
- 应用层
- 对应用户的层级、提供原始数据
- 功能:为应用提供网络服务接口,面向用户。
- 常用协议与端口:
- FTP:21(连接)/20(主动模式下,传输数据)
- HTTP:80
- HTTPS:443
- SMTP:25
- Telnet:23
- DNS:53
- 数据单位:数据 (Data)。
TCP/IP网络五层模型
- 是由OSI七层衍生而来,更明确的分析了网络数据传递过程
- 从底层到顶层分别是:
- 物理层
- 设备:网卡、网线
- 单位:比特流(bit)
- 数据链路层
- 设备:交换机
- 单位:数据帧
- 协议:802.3(有线网络),802.1q(虚拟网络)
- 网络层
- 设备:路由器
- 单位:数据包
- 协议:IP(Internet协议),ICMP(Internet控制报文协议,ping)、ARP(地址解析协议,RARP反向解析)
- 传输层
- 设备:防火墙
- 单位:数据段
- 协议:TCP,UDP
- 应用层
- 设备:计算机
- 单位:没有单位,提供原始数据
- 协议:FTP(文本传输协议,21、20,21端口用于客户机和连接服务器时使用,20端口用于主动模式下进行数据的传递),
- HTTP(超文本传输协议,80),
- HTTPS(安全超文本传输协议,443),SMTP(简单邮件传输协议,25),TELENT(远程登陆协议,23),SSH(22)
- DNS(域名解析,53),DHCP(动态地址分发协议,67)
数据传输流程(封装→传输→解封装)
- 封装(发送端:自上而下)
- 应用层→加端口(传输层)→加 IP(网络层)→加 MAC(数据链路层)→转比特流(物理层)。
- 解封装(接收端:自下而上)
- 比特流→拆 MAC→拆 IP→拆端口→还原应用数据。
- 中间设备转发
- 交换机:看MAC,转发帧。
- 路由器:看IP,选路由,重新封装帧。
核心速记
- MAC 地址→数据链路层→交换机。
- IP 地址→网络层→路由器。
- 端口号→传输层→TCP/UDP。
- 应用服务→应用层→HTTP/FTP/DNS 等。
三、网络传输介质
双绞线(网线)
- 1.屏蔽
- 1)成本较高,屏蔽效果好,在强磁环境、信号干扰强度大的环境下使用
- 2)外面有一层金属网膜进行信号屏蔽
- 2.非屏蔽
- 1)成本较低,目前企业、园区、学校等场景下使用
双绞线的特点以及应用场景
- 1)5类:仅支持10M、100M网络,目前已经淘汰
- 2)超5类:支持1000M及以上的网络传输,是目前接入层布线最常用的类型之一,成本较低
- 3)6类:支持1000M及以上的网络传输,可以在接入层,汇聚层或者核心层使用
- 4)7类:支持1000M及以上的网络传输,在汇聚层或者核心层使用
- 5)8类:支持1000M及以上的网络传输,在汇聚层或者核心层使用
光纤的特点
- 1)传输距离远
- 2)传递带宽高
- 3)抗干扰能力强
单模、多模光纤的区别
- 1.单模光纤
- 1)传输距离远,用于城市、省市之间使用
- 2)抗干扰能力强,传递带宽高
- 3)造价成本高
- 2.多模光纤
- 1)传输距离短,用于企业,大型园区之间使用较多
- 2)传递带宽相对较低
- 3)造价成本相对较低
双绞线线序
- 1.T568A:白绿、绿、白橙、蓝、白蓝、橙、白棕、棕
- 2.T568B:白橙、橙、白绿、蓝、白蓝、绿、白棕、棕
四、办公网络布线
综合布线系统
- 设备间子系统
- 核心组成:电缆、连接器、计算机、网络设备(核心交换机、路由器)
- 功能定位:是综合布线系统的‘核心机房’,连接其他子系统
- 拓扑/铺设方式:网络设备采用网型拓扑,保障可靠性
- 建筑群子系统
- 核心组成:光纤、长距离网线
- 功能定位:连接不同建筑的设备间,实现跨建筑数据传输
- 拓扑/铺设方式:埋地铺设线路,需预留线路冗余
- 垂直子系统
- 核心组成:光纤、主干网线、
- 功能定位:连接管理间子系统与设备间子系统,承担建筑内‘垂直主干传输’
- 拓扑/铺设方式:沿建筑物弱电井铺设,可选网型/星型拓扑
- 管理间子系统
- 核心组成:机柜、配线架、汇聚交换机
- 功能定位:是综合布线的‘中间枢纽’,连接垂直子系统和水平子系统
- 拓扑/铺设方式:采用星型拓扑,方便管理终端接入
- 水平子系统
- 核心组成:水平配线电缆、信息模块
- 功能定位:连接管理间子系统与工作区子系统,实现‘水平覆盖’
- 拓扑/铺设方式:沿天花板、墙壁线槽铺设,覆盖办公区各工位
- 工作区子系统
- 核心组成:终端连接线(跳线)、信息插座、适配器
- 功能定位:是综合布线的‘末端’,连接终端设备(计算机、打印机)与水平子系统
- 拓扑/铺设方式:信息插座部署在工位附近,方便终端接入
材料用量统计
- 信息模块与水晶头
- 信息模块:用量=工位数量+预留量(10---12个,对应损坏或新增工位)
- 水晶头:水晶头总量=工位数量*4*(1+预留比例) 如总量=8*4*(1+15%)
- 线缆用量
- 计算公式:C=[0.55*(L+S)+6]*n
- C:总用线量 单位:m
- 0.55:中间系数(平衡远近端线缆长度,包含备用量)
- L:本楼层离管理间最远的信息点距离 单位:m
- S:本楼层离管理间最近的信息点距离 单位:m
- 6:端接容差(预留6m,用于机房端、工位端的端接操作)
- n:本楼层信息点总数(即工位数量)
计算结果均向上取整 如:36.8个取整为40个,389.88m取整为400m
五、常见的网络协议
五、常见的网络协议
传输层协议(TCP/UDP)
- 传输层核心作用与通信方式
- 传输层接收应用层数据,封装传输层头部,建立‘端到端’通信,区别于数据链路层的‘点到点’通信
UDP协议(用户数据报协议)
- 全称:User Datagram Protocol,工作于传输层,依赖IP协议实现‘端口到端口’通信,IP报文中协议号为17;
核心特点
- 无连接性:无需建立连接即可发送数据,速度快;
- 不可靠性:不提供确认、重传、排序、流量控制,数据可能丢失或乱序;
- 简单性:协议头仅8字节(远少于TCP),传输开销小;
- 基础检错:通过校验和检测数据错误(仅检错,不纠错,错误则丢弃);
- 适用场景:实时性要求高、可容忍部分丢包的场景(如在线游戏、实时视频流、VoIP(网络电话))。
TCP协议(传输控制协议)
- 全称:Transmission Control Protocol,面向连接的可靠传输层协议,工作于OSI第四层;
- 核心特点
- 面向连接:数据传输前需通过‘三次握手’建立连接,传输后通过‘四次挥手’关闭连接;
- 可靠性:通过序列号、确认应答、重传机制保障数据无丢失、无重复、按序到达;
- 面向字节流:无固定报文段大小,数据按字节编号,接收端重组为原始数据流;
- 全双工通信:连接双方可同时发送和接收数据;
- 流量控制:通过滑动窗口算法调节发送速率,避免接收方缓冲区溢出;
- 拥塞控制:网络拥塞时减少发送量,避免拥塞恶化(如慢开始、拥塞避免算法)。
传输层核心:TCP vs UDP
- 通信方式区别
- 端到端:传输层,应用→应用,全程可靠(TCP)
- 点到点:数据链路层,相邻节点,仅帧传输(以太网)
- UDP(用户数据报协议)
- 特点:无连接、不可靠、开销小(头 8 字节)、仅检错不纠错
- 协议号:17
- 适用:游戏、直播、VoIP 等实时性优先场景
- TCP(传输控制协议)
- 特点:面向连接、可靠、全双工、流量 / 拥塞控制
- 头部:固定 20 字节,含Seq 序号、Ack 确认号、窗口、标志位
- 三次握手(建连):SYN → SYN+ACK → ACK
- 四次挥手(断连):FIN → ACK → FIN → ACK
- 机制:序号保证顺序、确认 + 重传保可靠、滑动窗口做流量控制
TCP首部核心字段
- 源端口/目的端口
- 长度:16
- 核心作用:标识发送方/接收方应用程序端口,与IP地址共同唯一确定TCP连接
- 序列号
- 长度:32
- 核心作用:标识本报文数据的第一个字节编号,确保数据按序传输
- 关键细节:每个字节均有唯一编号,如首字母为a+1,次字节为a+2
- 确认序列号
- 长度:32
- 核心作用:期望接收的下一个字节编号(已接收数据的最后字节编号+1)
- 关键细节:需与ACK标志位配合使用
- 控制位
- 长度:6
- 核心作用:控制连接状态与数据传输(URG/ACK/PSH/SYN/FIN)
- 关键标志:SYN(建立连接),ACK(确认),FIN(断开连接)
TCP建立连接--三次握手
- 三次握手的核心目的是’同步双方序列号,确认收发能力‘
- 第一次握手(客户端→服务器)
- 客户端发送SYN报文(SYN=1,ACK=0),携带随机初始序列号(如seq=100);
- 作用:请求建立连接,同步客户端序列号;
- 第二次握手(服务器→客户端)
- 服务器接收SYN后,回复SYN-ACK报文(SYN=1,ACK=1);
- 携带服务器初始序列号(如Seq=200),确认序列号=客户端Seq+1(如Ack=101);
- 作用:确认客户端请求,同步服务器序列号;
- 第三次握手(客户端→服务器)
- 客户端接收SYN-ACK后,发送ACK报文(ACK=1);
- 确认序列号=服务器Seq+1(Ack=201),自身序列号=初始Seq+1(如Seq=101);
- 作用:确认服务器响应,连接正式建立
FTP协议(文件传输协议)
- 全称:File Transfer Protocol,应用层协议,基于TCP实现可靠文件传输,由’FTP服务器+FTP客户端‘组成:
- FTP服务器:存储文件,提供文件访问接口
- FTP 客户端:通过命令与服务器交互,实现文件上传 / 下载
- 21 端口:控制连接(建立连接、传输命令,如 “上传 / 下载指令”)
- 20 端口:数据连接(仅主动模式下,传输文件数据)
FTP两种工作模式
- 主动模式(PORT):数据连接由服务器发起
- 流程:客户端→服务器 21端口建立控制连接,客户端告知服务器 “随机数据端口(如1024)”,
服务器→客户端随机端口(20 端口为源端口)建立数据连接,传输文件。
- 适用场景局域网(无防火墙拦截服务器主动连接)
- 被动模式(PASV):数据连接由客户端发起
- 流程:客户端→服务器 21端口建立控制连接,服务器告知客户端 “随机空闲端口(如5000)”
客户端→服务器随机端口建立数据连接,传输文件
- 适用场景:互联网(避免客户端防火墙拦截)
Telnet 协议
- 核心作用:应用层远程登录协议,基于 TCP,默认端口23,允许用户通过本地终端远程登录主机,执行命令操作。
- 特点:
- 交互式操作:模拟本地终端,可实时执行远程主机命令;
- 安全性低:数据传输不加密,账号、密码易被截获;
- 替代方案:SSH 协议(Secure Shell),默认端口 22,提供加密传输,安全性更高,已广泛替代 Telnet。
HTTP 协议(超文本传输协议)
- 全称:HyperText Transfer Protocol,应用层协议,基于 TCP,默认端口80,
用于 Web 浏览器与服务器间的数据传输(如 HTML、图片、视频);
ARP 协议(地址解析协议)
ARP 协议(地址解析协议)
- 全称:Address Resolution Protocol,网络层协议,IPv4 中必不可少。
- 核心作用:
- 根据 “已知 IP 地址” 解析对应的 “MAC 地址”(数据链路层需 MAC 地址封装帧)
- 维护 “IP-MAC 映射关系” 的 ARP 缓存表,避免重复解析
ARP协议过程
- 1.主机检查自己系统内部的ARP缓存表,如果有直接通过OSI七层模型的顺序打包封装发送数据
- 2.如果ARP缓存表中没有记录,发送一个ARP广播包(局域网内一对所有,交换机自动发送广播包),询问谁是那个IP地址
- 3.其他主机收到后丢弃,目标主机收到后携带自身的MAC地址回应请求方,并且将对方的MAC地址写入到自己的ARP缓存表中
- 4.主机将目标机的MAC地址保存到ARP缓存表中,实现单播通信
- ARP缓存表:表中记录着当前网段的IP+MAC地址的映射记录。每隔一段时间就会清空缓存表,一般是300s。
六、交换机工作原理
以太网基础
- MAC 地址
- 48 位(6 字节),全球唯一
- 前 24 位:厂商 OUI;后 24 位:设备唯一编号
- 格式:十六进制,如 00-00-00-11-11-11
- 以太网帧结构
- 前导码 + SFD + 目的 MAC + 源 MAC + 类型 / 长度 + 数据 + FCS
- 数据长度:46~1500 字节,不足自动填充
- FCS:CRC 校验,错误直接丢帧
交换机转发原理
- 交换机基于MAC地址表实现数据帧转发,交换机刚启动时MAC地址表为空。核心流程分为五步
- 1)初始状态——MAC地址表为空
- 2)MAC地址学习——记录源MAC与端口映射
- 3)广播未知域——寻找目的MAC
- 4)接收方回应——补充目的的MAC映射
- 5)单播通信——精准转发帧
- 交换机MAC地址缓存表每隔一段时间就会清空,一般是300s。
- 接口双工模式
- 单工:单向(已淘汰)
- 半双工:双向不同时(已淘汰)
- 全双工:双向同时,无冲突、效率高(当前默认)
- 接口速率
- 10/100/1000Mbps/10G
- 自动协商:默认开启,两端必须一致,否则丢包
华为交换机命令行为分为4种核心视图。视图可通过特定命令转换,功能权限不同
- 用户视图:标识符号<>。终端连接交换机后自动进入
- 核心功能:基础查询(如display,version查版本)保存配置
- 退出方式:输入system-view进入系统视图;输入quit退出终端
- 系统视图:标识符号[ ] 。在用户视图输入system-view(可简写为sys)
- 核心功能:全局配置(如改设备名,创建VLAN),进入其他视图
- 退出方式:输入quit退回用户视图,输入interface进入接口视图
- 接口视图:标识符号[接口名]。在系统视图输入interface 接口类型 接口号 (如 interface g 0/0/1)
- 核心功能:配置接口参数(速率,双工,IP地址)
- 退出方式:输入quit退回系统视图,输入return直接退回用户视图
- 功能视图:标识符号[功能名]。在系统视图输入功能命令(如vlan 10,ospf 1)
- 核心功能:配置特定功能(如VLAN,路由协议)
- 退出方式:输入quit退回系统视图
常用核心命令
- sysname 设备名 。需要在系统视图
- 核心作用:修改交换机名称(便于识别)
- 例:[Huawei] sysname SW1 (将设备名称改为SW1)
- display ip interface brief 。任意视图
- 核心作用:查看所有接口的IP地址、状态(UP/DOWN)
- 例:[SW1] display ip interface brief
- display mac-address。任意视图
- 核心作用:查看MAC地址表(含动态/静态表项)
- 例:[SW1] display mac-address.
- mac-address static MAC地址 接口 vlan 1。需要在系统视图
- 核心作用:静态绑定MAC地址(防止ARP欺骗)
- 例:[SW1] mac-address static 5489-98b4-2fa1 g 0/0/3 vlan 1
- sysname 改名
- display mac-address 查看 MAC 表
- display ip interface brief 查看接口
- undo negotiation auto 关闭自动协商
- mac-address static 静态绑定 MAC
七、VLAN技术原理与配置
vlan的概念
- 1.vlan叫做虚拟局域网,可以在一个大型的物理局域网中逻辑划分出若干个小型局域网
- 2.减少了广播包对设备以及线路资源的占用,提高了网络效率
- 3.不同vlan之间默认无法通信,提高了网络的安全性,方便了网络的扩展和管理
- 4.交换机每个接口默认绑定一个vlan,默认绑定vlan 1.
- 作用:逻辑划分广播域,隔离广播风暴,提升安全与效率
- 特点:同一 VLAN 可互通,不同 VLAN 默认不能直接互通,需三层设备(路由器 / 三层交换机)转发
交换机的接口类型,每个接口类型收发的vlan数据的动作都不一致,可以通过更改接口类型来管理vlan
- 1.access接口:接入类型
- 1)一般用于连接接入网络和终端设备,仅允许一个vlan通行
- 2)接收数据时,如果该端口收到的数据帧是untagged(不带标签的的),交换机则加上该端口的PVID(一般会通过port
default vlan 设置PVID,也就是vlan id);如果接收到的数据帧是tagged(带标签),交换机则检查vlan id,当vlan id和PVID相同时,传输数据,
不同,丢弃数据
不同,丢弃数据
- 3)access接口发送数据时永远是先剥离标签,然后发送
- 配置命令
- sys
- int g0/0/1
- port link-type access (简写:port l t a)
- port default vlan 10 (简写:port d v 10)
- 2.trunk接口:主干类型
- 1)一般用于连接网络设备,可以允许多个vlan通行
- 2)接收数据时,如果该端口接收到的数据帧是untagged(不带标签),交换机则加上该端口的PVID(trunk模式需要通过port
trunk pvid vlan 来设置trunk的PVID。),如果PVID在允许通过的vlan id 表中,则接收,否则丢弃。如果接收到的数据帧是tagged(带标签)则检查
vlan id表,如果在表中,则允许通过,反之丢弃。
vlan id表,如果在表中,则允许通过,反之丢弃。
- 3)只有当vlan id和pvid一致时trunk口才会剥离标签发送
- 配置命令
- sys
- int g0/0/24
- port link-type trunk (简写:port l t t)
- port trunk allow-pass vlan 10 20 (简写:port t a v 10 20)
- port trunk pvid vlan 1 (可选)
- 3.hybrid接口:混合模式
- 1)可以连接终端也可以连接其他网络设备,是交换机默认的接口类型
- 2)收发数据时与trunk类似需要定义允许通过的vlan id列表,并且需要手动设置标签的剥离,默认携带标签发出
- 配置命令
- sys
- int g0/0/3
- port link-type hybrid (简写:port l t h)
- port hybrid pvid vlan 10 (简写:port h p v 10)
- port hybrid untagged vlan 10 (发出去剥标签)
- port hybrid tagged vlan 20 (发出去带标签)
vlan的划分方式
- 总共分为5种,主要分为两大类
- 静态:基于端口
- 动态:基于MAC、基于IP、基于协议、基于策略
VLAN 基础命令
- 创建 VLAN
- vlan 10 (创建单个)
- vlan batch 10 20 30 (批量创建,简写:vlan b 10 20 30)
- vlan batch 10 to 20 (连续创建)
- 删除 VLAN
- undo vlan 10
- undo vlan batch 10 20
- 查看 VLAN
- display vlan (简写:dis vlan)
- display vlan summary (简写:dis vlan s)
- display port vlan active (简写:dis p v a)
- display current-configuration (简写:dis cu)
- 清空接口配置(改模式必须先清)
- clear configuration interface g0/0/3 (清空接口)
- undo shutdown (开启接口)
- 端口组批量配置(提高效率)
- port-group 1
- group-member g0/0/1 to g0/0/10
- port link-type access
- port default vlan 10
不同vlan通信的方式
- 1.单臂路由
- 1)通过进入路由器的虚拟接口配置不同的vlan信息以及IP地址(也就是下层设备的网关),vlan数据进入到路由器后会通过各自
的虚拟接口接收并进行转发
- 2)所有的流量全部基于一个物理接口,会导致单接口以及线路工作压力较大,容易出现流量拥塞或者故障问题
- 3)一般在中小型网络下使用
- 配置命令
- int g0/0/0.10
- dot1q termination vid 10
- ip address 192.168.10.1 24
- arp broadcast enable
- 2.三层交换机
- 1.企业最常用的一种方式,通过具备三层功能的交换机实现不同网段的转发,也称为三层交换机
- 2.进入到vlan接口中,针对vlan进行IP地址的配置,vlan的IP就是客户机的网关地址
- 配置命令
- interface Vlanif 10
- ip address 192.168.10.1 24
跨网段通信
- 1.跨网段通信时,所有的PC必须正确设置网关地址,否则无法连接其他网络
- 2.网关地址就是同网段的上层设备的接口IP地址,是真实存在的
- 3.路由器的物理接口以及交换机的逻辑接口设置IP地址,不允许设置为同一个网段
八、GVRP与链路捆绑
GVRP的概念
- GVRP是一种用于注册和注销vlan属性的协议,它允许交换机之间相互交换vlan的配置信息,从而实现动态创建和管理vlan
- 核心作用
- 交换机之间自动同步 VLAN,不用每台手动创建
- 必须跑在 Trunk 口 上
- 三种注册模式
- normal:默认,允许动态 / 静态 VLAN 注册
- fixed:只发静态 VLAN,不学习动态 VLAN
- forbidden:禁止 GVRP,只留 VLAN1
GVRP的接口注册模式
- normal模式
- 交换机端口默认为normal模式
- 允许静态vlan和动态vlan在端口注册、注销,同时会发送静态vlan和动态vlan的声明信息
- fixed模式
- fixed模式不允许动态vlan在端口注册或注销,并且只会发送静态vlan的声明信息
- forbidden模式
- 不允许动态vlan在端口注册或注销,同时删除端口上除了vlan 1外的所有vlan
- 也就是说设置了forbidden模式的端口不参与GVRP的vlan注册
GVRP 配置命令
- 全局开启 GVRP
- gvrp #简写:gvrp #作用:全局开启 GVRP 功能
- 配置 Trunk 接口并开启 GVRP
- interface GigabitEthernet 0/0/1 # 简写:int g0/0/1 # 作用:进入接口
- port link-type trunk # 简写:port l t t # 作用:设为Trunk(GVRP只能在Trunk跑)
- port trunk allow-pass vlan all # 简写:port t a v all # 作用:放通所有VLAN
- gvrp # 简写:gvrp # 作用:接口下开启GVRP
- 修改注册模式
- gvrp registration normal # 简写:gvrp reg n # 作用:设为normal模式(默认)
- gvrp registration fixed # 简写:gvrp reg f # 作用:设为fixed模式
- gvrp registration forbidden # 简写:gvrp reg fo # 作用:设为forbidden模式
- 查看 GVRP
- display gvrp status # 简写:dis gvrp s # 作用:查看GVRP全局状态
- display gvrp statistics # 简写:dis gvrp st # 作用:查看GVRP端口统计
- display vlan summary # 简写:dis vlan s # 作用:查看静态/动态VLAN
链路聚合概述
- 1.链路聚合是一种将多个物理端口捆绑在一起,形成一个逻辑端口的技术,主要目的是增加链路带宽和提高链路的可靠性
- 1)链路聚合组是将多条以太网物理链路捆绑在一起形成的逻辑链路
- 2)每个链路聚合组对应一个逻辑接口,也称为eth-trunk接口
- 3)这个逻辑接口可以像普通的以太网接口一样使用,但在数据转发时,需要从成员接口中选择一个或多个来进行数据转发
- 2.一般部署在核心层,提升整个网络的传输
- 3.链路聚合的要求
- 1)eth-trunk链路两端的物理接口参数必须一样,其中包括数量、速率、双工模式、流量控制等
- 2)每个eth-trunk口最多有8个成员
- 3)加入eth-trunk时接口必须是hybrid接口(一般交换机默认接口为hybrid接口)
- 4)eth-trunk接口不能嵌套,成员接口不能再次设置为eth-trunk(即一个接口不能同时出现在两个或多个eth-trunk中)
链路聚合 配置
- 创建 Eth-Trunk 并添加成员(逐条加)
- interface Eth-Trunk 1 # 简写:int Eth-Tr1 # 作用:创建聚合组1,进入逻辑口
- interface GigabitEthernet 0/0/1 # 简写:int g0/0/1 # 作用:进入物理口1
- eth-trunk 1 # 简写:eth-tr1 # 作用:把物理口加入聚合组1
- interface GigabitEthernet 0/0/2 # 简写:int g0/0/2
- eth-trunk 1 # 简写:eth-tr1
- 批量添加成员(更常用)
- interface Eth-Trunk 1 # 简写:int Eth-Tr1
- trunkport GigabitEthernet 0/0/1 to 0/0/3 # 简写:trunkp g0/0/1 to 0/0/3 # 作用:批量把1-3号口加入聚合组
- 配置聚合组为 Trunk
- interface Eth-Trunk 1 # 简写:int Eth-Tr1
- port link-type trunk # 简写:port l t t # 作用:聚合口设为Trunk
- port trunk allow-pass vlan all # 简写:port t a v all # 作用:放通所有VLAN
- 查看链路聚合
- display interface Eth-Trunk 1 # 简写:dis int Eth-Tr1 # 作用:查看聚合组状态、成员口、速率
- display eth-trunk 1 # 简写:dis eth-tr1 # 作用:查看聚合组概要
九、生成树协议
二层环路带来的问题
- 广播风暴:广播帧在环路中无限循环,占满带宽,网络瘫痪
- MAC 地址表震荡:同一 MAC 从多个端口学到,端口不断切换
- 解决办法:STP 生成树协议(逻辑阻塞端口,破环 + 冗余备份)
STP的工作原理
- STP通过逻辑上阻塞一个端口达到无环的网络拓扑结构,可以提高网络的稳定性和可靠性。
- 具体选举过程通过选择根网桥、跟端口、指定接口、阻塞接口形成无环网络
STP具体选举工作流程
- 1、当所有交换机全部启动后相互发送BPDU(网桥协议数据单元),包含交换机进行选举时的参数以及当前网络的运行状态
- 2、首先进行根网桥的选择
- 1)所有交换机相互发送BPDU数据报,网桥ID数值越小优先级越高
- 1.网桥ID由优先级数值+MAC地址组成
- 2.优先级数值范围在0~65536,默认是32768,管理员手动设置时必须是4096的倍数
- 3.对比时先对比优先级,如果优先级一样则查看MAC地址
- 2)根网桥是整个STP环境中最核心的存在,所有的流量都会经过根网桥进行转发,所以管理员一般都会参与选举,选择出
性能最好的设备来作为根网桥
- 3、其次在非根网桥设备的接口上选择根端口
- 1)优先选择到达根网桥路径成本最低的端口
- 2)其次对比网桥ID
- 3)最后通过端口ID进行选择,端口ID数值越小优先级越高
- 1.端口ID由优先级数值+端口编号组成
- 2.优先级数值范围是0~256,默认是128,管理员手动设置时必须是16的倍数
- 3)选择出根端口的意义就是选择出一个最快到达根网桥转发数据的端口
- 4、最后选择指定端口,每条链路上至少有一个指定端口,并且根网桥上的所有接口都是指定端口
- 1)优先选择到达根网桥路径成本最低的端口
- 2)其次对比网桥ID
- 3)最后对比端口ID
- 5、当所有端口选择完成后,默认剩余的端口为阻塞端口,也可以成为冗余端口、备用端口
STP运行启动后接口到转发时会经过5个状态
- 禁用状态:不收发任何数据
- 阻塞状态:仅接收BPDU报文,不发送任何数据
- 侦听状态:仅收发BPDU报文,开始参与STP角色的选举
- 学习状态:收发BPDU报文以及其他设备的MAC地址缓存记录,开始构建自身的MAC地址缓存表
- 转发状态:可以正常收发任何数据
STP 三个计时器
- Hello 时间:默认 2s,发送 BPDU 间隔
- Forward Delay:默认 15s,侦听 + 学习总时长
- Max Age:默认 20s,BPDU 老化时间
MSTP
- 多生成树协议,允许在物理网络中并行运行多个生成树实例,用于在支持VLAN的网络中提供优化的路径选择和负载均衡
- 主要目的是在保持网络稳定性的同时,提高数据转发的效率和容错能力
MSTP 配置命令
- stp enable # 简写:stp en # 作用:全局开启生成树
- stp mode mstp # 简写:stp m mstp # 作用:设置模式为 MSTP
- stp region-configuration # 简写:stp r c # 作用:进入 MSTP 域配置
- region-name ABC # 简写:reg n ABC # 作用:设置域名(域内必须一致)
- revision-level 1 # 简写:rev l 1 # 作用:设置修订级别(域内必须一致)
- instance 1 vlan 10 # 简写:ins 1 v 10 # 作用:实例 1 绑定 VLAN 10
- instance 2 vlan 20 # 简写:ins 2 v 20 # 作用:实例 2 绑定 VLAN 20
- active region-configuration # 简写:act r c # 作用:激活域配置(必须敲)
- stp instance 1 priority 4096 # 简写:stp ins 1 p 4096 # 作用:设置本设备为实例 1 根桥
- stp instance 2 priority 8192 # 简写:stp ins 2 p 8192 # 作用:设置本设备为实例 2 备份根桥
查看命令
- display stp brief # 简写:dis stp b # 作用:查看端口角色、状态、保护
- display stp # 简写:dis stp # 作用:查看完整生成树信息
十、静态路由器
网络层核心作用
- 跨网络转发数据包,负责路由选择、IP 寻址、分片与重组。
- 关键:IP 地址寻址、路由表选路、TTL 防环路。
路由器工作原理
- 路由器是一种网络设备,它工作在OSI参考模型的第三层——网络层,负责数据包的转发和路由选择。
- 它根据数据包中的网络层地址(通常是IP地址)和内部维护的路由表来决定数据包的输出端口和下一跳地址。
路由表中条目的生成方式
- 自动生成(直连路由):路由器自动将接口的直连网络生成到路由表中,在表中是优先级最高
- 手动添加(静态路由):通过配置静态路由,手动为路由器添加未知网段,优先级默认为 60
- 自主学习(动态路由):通过配置动态路由,路由器自动学习网络中的路由条目,由于路由协议的类别不一样,优先级也不相等,常见的动态路
由协议有:RIP、OSPF、BGP、IS-IS
静态路由
静态路由
- 定义:手动配置路由,不会自动更新。
- 优点:稳定、安全、占用资源少。
- 缺点:网络变化需手动修改,不适合大型网络。
- 适用场景:小型网络、固定链路、备份链路。
路由表中的优先级
- 路由表中通过优先级来判定先通过那条路径传输数据
- 优先级值越小约优先,范围是 0 - 255,静态路由可以手动指定优先级,范围是 1 - 255
默认路由
- 也被称为“网关路由”或“缺省路由”,是一种特殊的静态路由。
- 默认路由的主要特点是它匹配所有不与已配置的路由条目匹配的网络流量。换句话说,当路由器在路由表中找不到与数据包的目的地址
精确匹配的特定路由时,它会使用默认路由来转发该数据包。
浮动路由
浮动路由
- 浮动路由是一种网络冗余技术,主要用于提高网络的可靠性和稳定性
- 它涉及到配置两条静态路由,其中一条作为主路径,另一条作为备份路径。
静态路由三种类型
- 普通静态路由
- 作用:指定去往目标网段的路径
- ip route-static 目标网段 掩码 下一跳IP #简写:ip route 网段 掩码 下一跳 #作用:添加静态路由
- 默认路由(缺省路由)
- 作用:匹配所有未匹配网段,常用于出口网关
- ip route-static 0.0.0.0 0 下一跳IP #简写:ip route 0 0 下一跳 #作用:配置默认路由
- 浮动路由(备份路由)
- 作用:配置主备链路,主链路故障自动切换。
- 原理:配置更高优先级值(优先级更小更优先)
- 主路由:ip route-static 192.168.10.0 24 10.1.1.2
- 备路由:ip route-static 192.168.10.0 24 10.2.1.2 preference 70 #作用:设置优先级70,作为浮动备份路由
必背命令
- system-view #简写:sys #作用:进入系统视图
- interface GigabitEthernet 0/0/0 #简写:int g0/0/0 #作用:进入接口配置IP
- ip address 192.168.1.1 24 #简写:ip add 192.168.1.1 24 #作用:配置接口IP地址
- ip route-static 192.168.20.0 24 10.1.1.2 #简写:ip route 192.168.20.0 24 10.1.1.2 #作用:配置静态路由
- ip route-static 0.0.0.0 0 10.1.1.2 #简写:ip route 0 0 10.1.1.2 #作用:配置默认路由
- ip route-static 192.168.20.0 24 10.2.1.2 preference 70 #简写:ip route 192.168.20.0 24 10.2.1.2 pre 70 #作用:配置浮动路由
- display ip routing-table #简写:dis ip rou #作用:查看路由表
- save #简写:save #作用:保存配置
核心原理速记
- 静态路由 = 手动配置、稳定、不自动更新
- 默认路由 = 0.0.0.0 0,匹配所有网段
- 浮动路由 = 同一目标配两条,优先级不同做主备
- 优先级越小越优先
- 路由器转发流程:收包 → 查目标 IP → 查路由表 → 转发 / 丢包
十一、子网划分
在IPv4地址中,每个网段有两个IP地址是无法被使用的
- 广播地址:主机位全为 1
- 网段地址:主机位全为 0
- 可用主机数 = 2ⁿ − 2(n = 主机位数)
IPv4地址的分类
- A类地址:网络位为8位,主机位为24位。(单播地址)地址为:0.0.0.0-127.255.255.255
- 其中 0 和 127是无法被使用的,127是计算机中的特殊IP,用于测试本地网卡作为回环地址使用
- B类地址:网络号为16位,主机位为16位。(单播地址)地址为:128.0.0.0-191.255.255.255
- C类地址:网络位为24位,主机位为8位。(单播地址)地址为:192.0.0.0-223.255.255.255
- D类地址:(组播地址)地址为:224.0.0.0-239.255.255.255
- E类地址:(保留地址)地址为:240.0.0.0-255.255.255.255
针对A、B、C类IP分别制定了不同的私有网络范围
- A类:10.0.0.0 - 10.255.255.255 1 - 126
- B类:172.16.0.0 - 172.31.255.255 128 - 191
- C类:192.168.0.0 - 192.168.255.255 192 - 223
- 127.x.x.x属于特殊的网段,称为本地回环地址,测试本地网络
IP参数
- IP 地 址:计算机上网的唯一标识
- 子网掩码:确认当前IP地址所属网络范围
- 默认网关:当前网络范围的出口,跨网络通信时使用
- DNS地址:通过域名访问网络资源
子网划分四步法
- 看掩码,确定网络位 / 主机位
- 算块大小(256−掩码第四段)
- 确定网络地址、广播地址
- 确定可用 IP 范围
十二、IPv6
IPv6概述
- 具有更广泛的地址空间,总共有128位二进制组成,地址数量是2^128次方
- IPv6依旧有掩码的概念,在v6版本中称为前缀,前缀相当于是网络位,接口标识相当于是主机位
- 由于v6版本的地址较长不好修改、配置可以进行简写
- 每组可以省略前面的 0
- 每组连续的四个 0 可以简写为 一个 0
- 多个连续的组都是 0 可以使用"::"双冒号的方式代替,但是每个地址只能使用一次
IPv6中有三个比较重要的地址
- 全球单播地址,本地链路地址,本地回环地址
通信类型
- 单播,组播,任意播
IPv6配置IP地址的方法
- 手动配置,单播地址、本地链路地址的前缀永远是 64
- 自动生成,通过本地链路地址生成一个64前缀的ip地址
- IEEE EUI-64生成,前64为管理员手动设置,后64为通过MAC地址生成,MAC仅有48位,那么会在中间添加FFFE补齐到64位
并且将MAC地址的第七bit反向更改,即0改为1,1改为0
8:29 2025/11/78:28 2025/11/7
8:29 2025/11/78:28 2025/11/7
十三、VRRP
十三、VRRP
VRRP(虚拟路由冗余协议 Virtual Router Redundancy Protocol,简称VRRP)
- 通过两个及以上的物理路由器,生成一个或多个逻辑路由器,下层设备全部通过逻辑路由器进行网络访问
- 用于解决局域网中静态网关出现单点故障问题
- 两台物理路由器为主、备存在,主路由器通过下层设备发送给逻辑路由器的数据包进行转发,备用路由器监听主要路由器,如果主要路由器出现故障则升级为主路由提供网络转发功能
VRRP成员
- Master 路由器:真实提供转发功能的路由器,处理virtual-ip的数据包
- Backup 路由器:备用路由器,周期性监听Master路由器的健康状态
- Virtual 路由器:通过主、备路由器逻辑生成的,下层设备通过访问逻辑路由器让主路由提供服务
- ps:路由器根据优先级选举Master路由器,优先级范围是1 - 254,默认为100,越大越可能成为Master路由器,VRRP具有抢占功能
端口跟踪
- 当主、备设备线路没有问题,但是其他端口出现故障后Master设备降低优先级,成为BackupMaster跟踪其他端口,如果出现端口状态为down则直接降低优先级
VRRP 关键机制
- 通告机制(心跳)
- Master 每 1 秒发送一次 VRRP 通告
- Backup 连续 3 个周期 收不到通告 → 认为 Master 故障
- 立即切换为新 Master
- 抢占延迟(Preempt Delay)
- 作用:防止网络抖动导致频繁切换
- 配置延迟后,设备不会立即抢占
- 生产环境建议配置延迟 3~5 秒
- 端口跟踪(Track Interface)
- 作用:解决上行链路故障问题
- 当 Master 的上行口 Down,但 VRRP 链路正常
- 会自动降低优先级(例如降低 60)
- 让 Backup 升级为 Master,避免流量黑洞
常用命令
- vrrp vrid 10 virtual-ip 192.168.10.254 # 创建VRRP备份组 10 # 虚拟网关IP:192.168.10.254 # 所有PC网关设置为这个IP
- vrrp vrid 10 priority 150 # 优先级设置为150(大于默认100) # 让该设备成为 Master
- vrrp vrid 10 preempt-mode timer delay 5 # 抢占延迟 5 秒 # 避免网络抖动频繁切换
- vrrp vrid 10 timer advertise 2 # 心跳间隔改为 2 秒 # 默认 1 秒
- 配置端口跟踪
- vrrp vrid 10 track interface GigabitEthernet 0/0/1 reduced 60 # 跟踪上行接口 g0/0/1
- # 一旦接口DOWN,优先级自动降低 60 # 让Backup设备抢占成为Master
- 查看命令
- display vrrp # 查看VRRP全部详细信息(状态、优先级、Timer、Track)
- display vrrp brief # 查看VRRP简要信息(主备状态、组号、虚拟IP)
VRRP 作用总结
- 解决网关单点故障
- 实现网关冗余备份
- 故障自动切换、终端无感知
- 配合 MSTP、静态路由、浮动路由实现企业级高可靠网络
- 是园区网、企业网中最核心的可靠性技术之一
十四、
交换机堆叠介绍
- 交换机堆叠是指将多台支持堆叠特性的交换机通过堆叠线缆连接起来,从逻辑上虚拟成一台交换设备,该交换机中的所有交换机共享相同的
配置信息和路由信息。当向逻辑交换机增加和减少单体交换机时不会影响其工作。
优势
优势
- 增强可靠性:多台设备互为备份,Master 故障时 Standby 立即接管,无业务中断。
- 扩展端口数量:直接增加端口数量、背板带宽,支持热插拔
- 提高网络带宽:多台设备链路可做链路聚合,大幅提高上行吞吐能力
- 简化网络配置和管理:逻辑上是一台设备,登录任意一台即可管理全体,降低维护成本
堆叠系统中所有的单台交换机都称为成员交换机,按照功能不同,可以分为三种角色
- 主交换机(Master):主交换机负责管理整个堆叠。堆叠系统中只有一台主交换机。
- 备交换机(Standby):备交换机是主交换机的备份交换机。堆叠系统中只有一台备交换机。当主交换机故障时,备交换机会接替原主交
换机的所有业务。
- 从交换机(Slave):从交换机用于业务转发,堆叠系统中可以有多台从交换机。从交换机数量越多,堆叠系统的转发带宽越大。
- 堆叠中所有成员交换机的堆叠ID都是唯一的
堆叠 ID 与优先级
- 堆叠 ID(Slot ID)
- 成员唯一编号,用于标识设备
- 必须唯一,不能重复
- 默认是 0,可手动修改
- 优先级
- 范围:1~255,默认 100
- 值越大越优先选为 Master
- 选举规则
- 先比较启动时间(相差 < 20 秒视为相同)
- 再比较优先级,大的胜出
- 优先级相同,比较 MAC 地址,小的胜出
堆叠的类型
- 环形堆叠
- 稳定性好,有一定的物理位置要求
- 更加安全一些,因为当环形堆叠中某台设备出现的故障后则变改为链形堆叠,不影响业务线的正常工作
- 链形堆叠
- 对设备的物理位置要求较低
- 主要用于设备物理位置较为分散的组网
- 安全性较低,中间设备出现故障后会引起堆叠分裂,可能导致部分业务无法联网
堆叠接口
- 使用专用集群卡和专用的堆叠线缆堆叠
- 将专用的集群卡插入到交换机扩展面板中,不占用原有业务口
- 需要额外采购部件,提高了业务成本
- 使用交换机业务口和普通线缆
- 直接使用物理接口做堆叠,无需重新采购额外部件,降低了成本
- 这种方式依赖设备的性能,随着设备性能越来越高,此类方式将会成为主流方式
堆叠配置命令
- 配置堆叠 ID
- stack slot 0 renumber 0 #作用:设置本设备的堆叠编号(必须唯一)
- stack slot 0 renumber 1 #作用:修改为堆叠 ID 1
- 配置堆叠优先级
- stack slot 0 priority 200 #作用:设置堆叠优先级,值越大越容易成为 Master,修改后重启生效
- 创建逻辑堆叠口(业务口堆叠)
- interface stack-port 0/1 #作用:创建逻辑堆叠接口
- port interface GigabitEthernet 0/0/1 enable #作用:将物理口加入逻辑堆叠口
- interface stack-port 0/2
- port interface GigabitEthernet 0/0/2 enable #作用:配置第二个逻辑堆叠口(用于环形)
- 查看堆叠状态命令
- display device #作用:查看成员设备数量、型号、状态
- display stack #作用:查看堆叠拓扑、角色、MAC、优先级
- display stack peers #作用:查看堆叠邻居关系
- display stack port #作用:查看物理堆叠端口状态
- display stack configuration #作用:查看堆叠配置信息
十五、ACL
ACL
- 访问控制列表ACL(Access Control List)是由一条或多条规则组成的集合。
- 所谓规则,是指描述报文匹配条件的判断语句,这些条件可以是报文的源地址、目的地址、端口号等。
- 通常用于标识感兴趣的网络流量,过滤经过路由器的数据包
- 作用:对数据包进行过滤、允许 / 拒绝,实现流量控制与安全策略
- 本质:一组规则集合,按源 IP、目的 IP、协议、端口号匹配流量
- 应用:接口入方向 / 出方向、Telnet/FTP/HTTP 等服务控制
ACL的分类
- 基本ACL
- 这是最简单的ACL类型,只允许源IP地址的过滤,适用于简单的网络环境,编号为:2000 - 2999
- 高级ACL
- 提供了更复杂的匹配条件,如源地址、目的地址、端口号等,允许更精细的流量控制。编号为:3000 - 3999
- 二层ACL
- 二工作在数据链路层(第二层),主要基于MAC地址进行过滤,适用于局域网内部的访问控制。编号为:4000 - 4999
- 用户ACL
- 允许管理员自定义规则,提供灵活性和可扩展性,适用于需要高度定制化的网络环境。编号为:5000 - 5999
ACL的匹配规则
- ACL是多条规则的集合,那么就需要有匹配条目的优先级
- 按照条目中的rule编号从小到大按照顺序匹配
- 如果命中目标则应用不会向下匹配
- 严格遵守匹配即停止的机制
- 如果没有命中任何规则则根据业务模块来处理
- 一般流策略是被默认允许的
- 其他网络协议如:Telnet是默认被拒绝的
- 华为设备支持两种添加条目顺序的方式
- 顺序匹配:
- 默认的增加条目方式
- rule编号可以由管理员在创建条目时手动设置也可以按照ACL的“步长”自动添加,自动添加的条目永远在最后一条。
- “步长”永远为 5 的倍数
- 深度匹配(自动匹配)
- 管理员无法手动修改rule编号,必须按照设备自主完成
- 按照“深度优先”的原则进行匹配,根据条目的精准度排序
- 如果匹配条件(如协议类型、源和目的IP地址范围等)限制越严格,规则就越优先匹配。
通配符掩码(反掩码)
- 0:必须匹配(检查该位)
- 1:忽略(不检查该位)
- host 192.168.1.1 = 192.168.1.1 0.0.0.0
- any = 0.0.0.0 255.255.255.255
基本 ACL 配置
- acl 2000
- rule 5 permit source 192.168.1.0 0.0.0.255(反码)
- rule 10 deny source any
高级 ACL 配置
- acl 3000
- rule 10 permit tcp source 192.168.1.0 0.0.0.255 destination 10.0.0.0 0.255.255.255 destination-port eq 80
- rule 20 deny ip any any
基于时间的 ACL
- 周期时间段
- time-range work 8:00 to 18:00 working-day
- 绝对时间段
- time-range fix from 00:00 2025/01/01 to 23:59 2025/12/31
- 在 rule 中调用
- rule 5 deny ip any any time-range work
命名 ACL
- acl name WorkACL basic 2000
- acl name WebACL advance 3000
ACL 应用到接口(当设置好了ACL,需要将ACL应用到接口中)
- interface g0/0/1
- traffic-filter inbound acl 3000 inbound:入方向
- traffic-filter outbound acl 2000 outbound:出方向
十六、NAT地址转换
NAT 作用与背景
- 解决 IPv4 地址枯竭,私网地址不能在互联网上路由
- 私网地址访问互联网必须做 NAT 地址转换
- 一般部署在出口路由器 / 防火墙上,连接内网与外网
- 分为 SNAT(源地址转换) 和 DNAT(目的地址转换)
私有地址范围
- A 类:10.0.0.0 ~ 10.255.255.255
- B 类:172.16.0.0 ~ 172.31.255.255
- C 类:192.168.0.0 ~ 192.168.255.255
NAT
- SNAT 源地址转换
- 静态NAT
- 实现一对一的地址转换,无法满足大量私有地址连接互联网的情况,使用概率极小
- interface 外网口
- nat static global 公网IP inside 私网IP
- display nat static
- 动态NAT
- 实现多对多的地址转换,但是每个IP地址无法同时被使用,无法保证内网所有主机上网
- 需要通过 ACL 进行流量分类,确认哪些地址经过路由器时可以被转换
- nat address-group 1 起始公网IP 结束公网IP
- acl 2000
- rule permit source 私网网段 反掩码
- interface 外网口
- nat outbound 2000 address-group 1 no-pat
- display nat address-group
- NAPT
- 实现多对多、多对一地址复用地址转换,可以保证内网所有用户上网,通信时,每个用户使用相同IP不同端口连接外网
- 需要通过 ACL 进行流量分类,确认哪些地址经过路由器时可以被转换
- nat address-group 1 起始公网IP 结束公网IP
- acl 2000
- rule permit source 私网网段 反掩码
- interface 外网口
- nat outbound 2000 address-group 1
- 区别:不加 no-pat 就是 NAPT
- Easy-ip
- 实现多对一复用地址转换,直接使用公网接口IP地址,不需要指定公网地址
- 一般在拨号上网的网络中使用,依旧需要通过 ACL 进行流量分类,确认哪些地址经过路由器时可以被转换
- acl 2000
- rule permit source 私网网段 反掩码
- interface 外网口
- nat outbound 2000
- DNAT 目的地址转换
- NAT-Server(端口映射)
- 将内网中使用私有地址的服务器挂载(映射)到公网中
- 让互联网中的用户可以通过访问公网IP地址的方式获取内网服务器的资源
- interface 外网口
- nat server protocol tcp global 公网IP 80 inside 私网服务器IP 80
- nat server protocol tcp global 公网IP 21 inside 私网服务器IP 21
- display nat server
核心总结
- SNAT(源 NAT):内网访问互联网用
- 静态、动态、NAPT、Easy-IP
- DNAT(目的 NAT):外网访问内网服务器用(隐藏内网服务器)
- NAT Server
- 所有配置必须在外网接口下调用
十七、RIP路由协议
动态路由协议基础
- 核心定义:动态路由协议是路由器自动学习、更新网络拓扑,并计算最优路由路径的协议
- 核心特点:自动适配网络变化:链路故障或新增设备时,自动调整路由,无需人工干预
- 降低管理成本:无需手动配置每条路由,大幅减少大型网络的运维工作量
- 分类
- IGP(内部网关协议):AS 内部使用 → RIP、OSPF、ISIS
- EGP(外部网关协议):AS 之间使用 → BGP
- 两类路由协议
- 距离矢量:传整张路由表,按跳数选路 → RIP
- 链路状态:传拓扑信息,SPF 算最优路 → OSPF
动态路由协议分类
- 距离矢量路由协议:路由器定期向相邻设备发送完整路由表,基于邻居反馈更新自身路由
- 典型协议:RIP、BGP。
- 核心度量指标:RIP:跳数;BGP:多种属性(如 AS 路径)
- 链路状态路由协议:通过 LSA(链路状态通告)交换拓扑信息,构建全网拓扑图,用 SPF算法计算最短路径
- 典型协议:OSPF、ISIS
- 核心度量指标:带宽、跳数、接口参数、等综合指标
自治系统(AS)与路由协议对应关系
- 自治系统定义:由统一管理、使用相同内部路由策略的网络设备组成,拥有独立 IP 地址空间和路由域,每个 AS内仅运行一种内部路由协议。
- 路由协议分类(按AS范围)
- 内部网关协议(IGP):自治系统内部使用,如RIP、OSPF、ISIS
- 外部网关协议(EGP):自治系统之间使用,如BGP(互联网核心路由协议)
RIP 路由协议核心特性
- 本质:典型的距离矢量路由协议,基于"跳数"作为路由度量值(1跳=经过1台路由器)
- 使用场景:中小型网络(最大跳数限制为15,16跳及以上视为不可达,无法适配大型网络)
- 工作机制
- 启动初期:路由器发送路由更新请求,邻居路由器相应自身路由表
- 网络稳定后:周期性发送路由更新(默认30秒),维持路由表同步
RIP-2与RIP-1版本对比
- 发送方式:支持广播和组播(224.0.0.9),组播减少网络开销
- 报文内容:包含子网掩码、认证信息、路由标记等,支持 VLSM/CIDR
- 认证功能:支持明文或 MD5 认证,防止恶意路由攻击
- 子网支持:支持可变长子网掩码,可精确通告子网路由
- 应用场景:中型网络,需子网划分、VLSM或高安全性需求
RIP 避免环路的机制
- 水平分割:路由器从某一接口学到的路由,不会再从该接口反向发送给邻居,防止路由信息在相邻路由器间循环传播
- 毒性反转:路由器从某一接口学到路由后,将该路由的跳数改为 16(不可达),再从原接口发回邻居,快速告知邻居该路由不可用,加速路由收敛
- 注意:水平分割与毒性反转同时配置时,毒性反转生效
动态路由与静态路由的核心区别
- 静态路由
- 配置方式:管理员手动添加、维护
- 资源消耗:几乎不占用路由器 CPU / 带宽
- 适应能力:网络拓扑变化后需手动修改,灵活性差
- 适用场景:小型稳定网络(如家庭、小型办公室)
- 路由优化 :依赖管理员经验配置最优路径
- 动态路由(以 RIP 为例)
- 配置方式:路由器自动学习、更新
- 资源消耗:需周期性发送更新报文,消耗一定资源
- 适应能力:自动适配拓扑变化,无需人工干预
- 适用场景:中大型或拓扑多变的网络(如企业、校园网)
- 路由优化:按协议度量值(如 RIP 跳数)计算路径
Loopback 接口
- 定义:路由器的逻辑接口,不依赖物理接口,永久 UP(除非手动关闭)
- 核心用途:作为管理地址,方便远程登录配置
- 用于网络测试(如本章节上机作业中 PC ping 测试)
- 作为路由协议的 Router ID(如 OSPF),提高稳定性
RIP 完整配置命令
- 启动 RIP 进程
- rip 1 #进入 RIP 进程 1
- viersion2 #指定版本 2
- 宣告直连主类网段
- network 192.168.1.0
- network 10.0.0.0
- 只允许主类网络,不能带掩码
- 水平分割(接口下默认开启)
- interface g0/0/0
- rip split-horizon
- 毒性反转(接口下)
- interface g0/0/0
- rip poison-reverse
- 静默接口(只收不发更新)
- silent-interface g0/0/1
- 查看命令
- display rip
- display ip routing-table protocol rip
十八、OSPF基础
OSPF 概述
- 全称:Open Shortest Path First(开放最短路径优先)
- 类型:链路状态协议、IGP 内部网关协议
- 适用:中大型网络,支持大规模、高带宽、多层次结构
- 优点:无环路、支持 VLSM/CIDR、收敛快、按链路开销选路(不看跳数)
- 组播地址:224.0.0.5(所有 OSPF 路由器)、224.0.0.6(DR/BDR)
OSPF 三张表
- 邻居表:记录邻接状态
- LSDB 链路状态数据库:全网拓扑图
- 路由表:SPF 算法计算的最优路由
OSPF工作原理
- 1、首先通过七个状态五种报文进行邻居关系的建立
- 2、相互通过发送 LSA 完善LSDB
- 3、通过 lsdb 中的数据计算出最优的路由条目并且写入到路由表中,实现数据转发
邻居建立过程
- 1、ospf首先进行邻居关系的建立,通过执行7个步骤相互发送5种报文完成建立
- 1)down状态:未启动 ospf 进程
- 2)init状态:接收到对等体发送的hello报文,发现邻居启动了 ospf 进程,请求建立
- 3)2-way状态:双发完全收发到了 hello 报文
- 4)exstart状态:通过发送 dd 报文确认主从关系,永远是主给从发
- 5)exchange状态:通过 dd 报文发送自身的链路状态信息
- 6)loading状态:通过 lsr、lsu、lsack继续完善lsdb,形成一套完整的拓扑结构
- 7)full状态:具有完整的链路状态信息,计算出路径树实现数据的转发
- 2、5个报文的简介
- hello报文:健康检查报文,用于建立维护邻居关系
- dd报文:数据库描述报文,用于确认主从关系,并且相互发送链路状态信息
- lsr:link status request 链路状态请求报文,请求对等体更多的信息
- lsu:link status update 链路状态更新报文,收到 lsr 后,写在想要的信息通过 lsu 回应
- lsack:link status Acknowledge 链路状态确认包,收到那个 lsu 后通过 lsack 确认收到
DR和BDR
- 1、DR是指定路由器,DBR是他的备用路由
- 2、减少广播型网络下 ospf 邻居建立的数量,减少广播报文的发送
- 3、选举过程
- 1)优先级默认是 1 ,数值越大优先级越大,范围是 1 - 255
- 2)优先级一样对比 rid ,数值越大优先级越高
- 3)不具备抢占功能,时间成了第一要素
route ID
- 1、ospf 环境内每一个路由器都具备有个 route-id,是路由器的标志,绝对唯一的
- 2、在启动 ospf 进程是手动指定 route-id 的方式是优先级最高的
- 3、如果不指定则自动生成
- 1)首先采用 loopback 接口中最大的IP地址,其次选择物理接口中最大的 IP 地址(不考虑 up/down 状态)
OSPF区域以及路由器角色
- 1、OSPF协议是通过多个区域组成,每个区域管理自己的路由表,主要分为三个区域
- 1)骨干区域:区域号永远是 0 ,其它所有区域需要连接到骨干区域中汇总路由信息
- 2)普通区域:区域号大于 0,必须连接到骨干区域中,每个普通区域之间不会相互发送路由状态
- 3)特殊区域:在普通区域基础上实现,主要是为了减少路由器的路由条目数量,减少路由器的工作压力
- 2、路由器角色
- 1)内部路由器(internal Router):
- 区域内没有连接其他任何区域的路由器,仅通过当前区域的路由器学习路由信息
- 2)区域边界路由器(area border router,ABR)
- 连接其他区域的路由器,用于汇总当前区域的路由信息发往到另一个区域中
- 3)自治系统边界路由器(Autonomous System Boundary Router,ASBR)
- 连接其他AS的路由器,用于汇总当前AS的路由信息发往到另一个AS中
网络类型
- 1、点对点(P2P)
- 1)路由器直连的状态可以使用此类型,不会进行DR、BDR的选举
- 2、点对多点(P2MP)
- 1)一个路由器连接其他多个路由器,并且没有多个线路,也不会进行DR、BDR的选举
- 3、广播(broadcast)
- 1)每个路由器有多个链路,默认需要建立多个邻居关系,需要完成DR和BDR的选举,也是ospf默认的网络类型
- 4、NBMA网络
- 1)在帧中继网络中使用
OSPF 配置命令
- sys
- ospf 1 router-id 1.1.1.1 // 启动OSPF并指定RID
- area 0 // 进入区域0
- network 192.168.1.0 0.0.0.255 // 宣告网段(反掩码)
- 常用附加配置
- silent-interface g0/0/1 // 静默接口(不发Hello)
- ospf network-type p2p // 修改网络类型为点对点
- ospf cost 10 // 修改接口开销
- display ospf peer // 查看邻居
- display ospf lsdb // 查看数据库
- display ip routing-table protocol ospf // 查看OSPF路由
OSPF 核心一句话总结
- OSPF 是链路状态协议,靠 Hello 建邻、LSA 同步拓扑、SPF 算最优路由;
- 用 RID 标识设备,广播网选举 DR/BDR;
- 按 Cost 开销选路,支持区域分层,适合大型园区网与企业网。
十九、OSPF高级
OSPF常见的链路状态通告
- LSA-1 router
- 每个路由器都会产生,主要用于建立邻居关系,仅在当前区域内传播
- LSA-2 network router
- 区域内路由器在广播型网络中进行 DR 角色选举时使用,仅在当前区域内传播
- LSA-3 network summary
- 由ABR路由器产生,用于汇总一个区域的路由信息传播到另一个区域中,仅在 AS 内传播
- LSA-4 ASBR summary
- 由ABR路由器产生,用于告知整个 AS 环境内所有路由器 ASBR 路由器的位置,仅在 AS 内传播
- LSA-5 AS External
- 由ASBR路由器产生,用于汇总一个 AS 内的路由信息传播到另一个AS中
- 外部路由引入内部时有两个类型
- Type-1:成本计算为内部+外部的总和
- Type-2:仅计算外部成本,也是默认的类型
- LSA-6
- 目前为保留类型,未使用
- LSA-7 nssa
- 非纯末梢区域独有的通告类型,仅在 nssa 区域内传播,nssa区域引入外部路由进入后转为 lsa-5 再传播到 AS 内部
特殊区域
- stub 末梢区域 | 末节区域
- 1、只能在网络最终节点使用,不可以被其他区域穿越
- 2、仅学习当前 AS 内部的路由信息,由ASBR引入进来的路由信息不会学习,并且 stub 中不允许连接其他 AS
- 3、需要在区域内的所有路由器中输入:stub即可
- 4、可以传播 LSA-1、LSA-2、LSA-3
- totally stub 完全末梢区域
- 1、只能在网络最终节点使用,不可以被其他区域穿越
- 2、仅学习当前区域的路由信息,更大缩减了路由条目,不允许连接其他 AS
- 3、需要在区域内的所有路由器中输入:stub no-summary 即可
- 4、可以传播 LSA-1、LSA-2
- nssa 非纯末梢区域
- 1、无法被当前 AS 内的其他区域穿越,可以存在 ASBR 路由器连接其他 AS
- 2、通过 lsa-7 链路状态通告类型将其他 AS 的路由信息引入到当前NSSA区域中,在本区域将LSA-7转为LSA-5再发送到本 AS 内
- 3、需要在区域内的所有路由器中输入: nssa 即可
- 4、可以传播LSA-1、LSA-2、LSA-5、LSA-7
OSPF 选路规则(优先级从高到低)
- 区域内路由 Intra Area(O)
- 区域间路由 Inter Area(O IA)
- Type1 外部路由(O E1)
- Type2 外部路由(O E2)
- E1 开销 = 内部开销 + 外部开销
- E2 开销 = 外部开销(默认)
虚链路
- 1、当物理环境导致普通区域无法直接连接骨干区域或者骨干区域被分割时使用
- 2、需要在被穿越的区域中的两个 ABR 路由器设置虚链路命令,互相指向对方的 RID
- 3、使用 display router id 命令查看当前设备的 RID,然后进入到需要穿越的区域中输入 vlink-peer {另一个ABR路由器的RID}
- ospf 1
- area 1
- vlink-peer 对方ABR的RID
路由引入
- 在 OSPF 中引入其他协议路由
- ospf 1
- import-route static
- import-route rip
- import-route direct
- 产生 Type5 LSA 或 Type7 LSA(NSSA)
- 路由聚合
- 在 ABR 上做区域间聚合:
- ospf 1
- area 1
- abr-summary 192.168.0.0 255.255.252.0
- 在 ASBR 上做外部路由聚合:
- ospf 1
- asbr-summary 10.0.0.0 255.0.0.0
重点命令总结
- # 配置Stub
- area 1
- stub
- # 配置Totally Stub
- area 1
- stub no-summary
- # 配置NSSA
- area 1
- nssa
- # 路由聚合(ABR)
- area 1
- abr-summary 192.168.0.0 255.255.252.0
- # 引入外部路由
- ospf 1
- import-route static
- # 虚连接
- area 1
- vlink-peer 2.2.2.2
- # 查看
- display ospf lsdb
- display ospf vlink
- display ospf peer
二十、BGP路由协议
BGP 基础概念
- 全称:Border Gateway Protocol 边界网关协议
- 类型:EGP(外部网关协议),用于AS 自治系统之间的路由传递
- 传输层:基于 TCP,端口 179
- 地位:互联网核心路由协议,运营商之间、企业多 AS 互联必用
BGP 核心特点
- 专门用于 AS 之间路由(OSPF/RIP 是 AS 内部)
- 基于 TCP,可靠传输
- 海量路由条目支持
- 极强策略控制(靠路径属性选路)
- 无广播、无洪泛,只跟对等体交换路由
BGP核心定义与定位
- 全称Border Gateway Protocol(边界网关协议),属于外部网关协议(EGP),运行在 TCP 协议之上(端口179),核心作用是实现不同自治
系统(AS)间的路由互通与策略控制。
- 核心价值:互联网的骨干路由协议,负责 AS 间路由信息交换,支持大规模网络互联,可通过灵活的路径属性与策略控制,精准选择路由路径。
BGP 的分类
- BGP 按运行场景分为外部 BGP(eBGP)和内部 BGP(iBGP)
- eBGP: 不同 AS 间交换路由信息
- 路由传播时更新AS_PATH,邻居为不同 AS 的路由器,默认 TTL 值为 1
- 配置时需要明确配置邻居的IP地址与所属AS号
- iBGP: 同一 AS 内同步 eBGP学习到的路由信息
- 路由传播时不修改AS_PATH,邻居为同一 AS 的路由器,需避免路由环路(全连接或路由反射器)
- 配置时需要配置Router ID,推荐采用路由反射器减少邻居数量
BGP 工作机制
- BGP 的核心工作流程包括 “对等体建立→路由交换→连接维护”,依赖 5 种协议报文和 6 种状态机实现
五种核心协议报文
- Open 报文 :用于建立BGP对等体连接,协商会话参数,当TCP建立连接后发送,关键内容是版本号,本地AS号、保持时间、Router ID
- Update报文:用于通告新增路由、撤销无效路由、修改路由属性,当拓扑变化或配置更新时发送,关键内容是撤销路由列表、路径属性列表、网络层可达信息
- Notification 报文:用于通知错误信息,中断BGP 连接,当检测到错误时发送,关键内容是错误代码、错误子代码、错误详情
- Keepalive 报文:用于维护 BGP 连接活性,周期性发送(默认保持时间是1秒或者3秒)关键内容是仅包含 BGP 报文头,无额外字段
- Route-refresh 报文:用于请求对等体重发路由信息,当本地配置变化后手动 /自动发送,关键内容是地址族标识符(AFI)、后续地址族标识符
六种状态机
- Idle(空闲状态):初始状态,BGP 进程未启动活动,等待触发事件(如手动启动 BGP);触发后尝试建立 TCP连接,进入 Connect 状态。
- Connect(连接状态):正在尝试与对等体建立 TCP 连接;连接成功则进入 OpenSent 状态,失败则进入 Active状态。
- Active(活跃状态):TCP 连接失败后,持续重试建立连接;连接成功则进入 OpenSent 状态,重试超时则返回Idle 状态。
- OpenSent(Open 报文已发送):已发送 Open 报文,等待对等体的 Open 报文;收到合法 Open 报文则进入OpenConfirm 状态,收到错误报文则发送 Notification 并返回 Idle 状态。
- OpenConfirm(Open 报文已确认):已收到对等体的 Open 报文,等待 Keepalive 或 Notification 报文;收到Keepalive 则进入 Established 状
态,收到 Notification 则返回 Idle 状态。
- Established(连接已建立):对等体关系稳定,可正常交换 Update、Keepalive、Route-refresh 报文;检测到错误则发送 Notification 并返回 Idle 状态。
BGP 路由引入
- BGP 支持通过两种方式引入外部路由(如 OSPF、RIP、静态路由)
- Import 方式:按协议类型批量引入路由,(如 OSPF、RIP、静态路由),常用于批量引入某类协议的路由
- bgp 10
- import-route static
- import-route ospf 1
- import-route rip
- Network 方式:精准引入指定网络地址的路由(需存在于本地路由表),常用于精准宣告核心业务网段,必须已经存在于路由表中
- bgp 10
- ipv4-family unicast
- network 192.168.100.0 255.255.255.0
避免环路
- 全连接:所有 iBGP 路由器两两建立邻居关系,适用于小规模 AS(邻居数量少);
- 路由反射器(RR):指定一台路由器作为反射器,其他 iBGP 路由器(客户机)仅与 RR 建立邻居,RR 负责反射路由,适用于大规模 AS(减少邻居数量)。
BGP 配置
- sys
- bgp 10 # 启动BGP,指定AS号
- router-id 1.1.1.1 # 配置RID(必须唯一)
- peer 202.0.0.2 as-number 20 # 配置eBGP邻居
- peer 10.1.1.2 as-number 10 # 配置iBGP邻居
- ipv4-family unicast # 进入IPv4地址族
- network 192.168.100.0 255.255.255.0 # 发布路由
对等体组(简化配置)
- bgp 10
- group IBGP_GROUP internal # 创建iBGP组
- peer IBGP_GROUP as-number 10
- peer 10.1.1.1 group IBGP_GROUP
- peer 10.1.1.2 group IBGP_GROUP
iBGP 路由反射器 RR(解决 iBGP 全连接问题)
- RR(路由反射器):把从客户机学到的路由反射给其他客户机 / 非客户机
- Client(客户机):只和 RR 建邻
- bgp 10
- peer 10.1.1.1 reflect-client # 指定客户机
- peer 10.1.1.3 reflect-client
查看命令
- display bgp peer # 查看邻居状态(必须是 Established)
- display bgp routing-table # 查看BGP路由表
- display bgp interface # 查看BGP接口信息
总结
- BGP 是 AS 间的路由协议,基于 TCP;
- 分 eBGP(跨 AS)和 iBGP(同 AS);
- 靠 Update 传路由,靠状态机建邻;
- iBGP 用路由反射器解决环路;
- network 精准发布,import 批量引入;
- 运营商、企业多 AS 互联必用。
二十一、WLAN
WLAN频段使用
- WLAN主要工作在2.4GHz和5GHz这两个频段,其中2.4GHz频段由于其较好的穿透能力和较广的兼容性,被广泛应用于各种无线设备中。
而5GHz频段则提供了更快的数据传输速率和更少的干扰。
WLAN中的设备概述
WLAN中的设备概述
- AC:称为无线控制器(Access Controller),主要负责管理和控制网络中的所有AP
- AP:称为无线接入点(Access Point),是连接无线网络和有线网络的关键设备
- 胖AP(Fat AP):一般用在家庭或者小型办公室中,是一款集成设备,可以独立完成工作,不需要AC进行控制,配置简单,成本比较低。
- 瘦AP(Fit AP):适合在中大型网络环境中,需要与AC配合使用,一个AC可以同时管理多个AP接入点
- 云管理AP:是新兴的模式,通过云服务进行管理,具有更大的灵活性以及扩展性,可以通过云端界面进行管理配置,适合需要远程管
理的场景
WLAN在家庭应用
WLAN在家庭应用
- 家用路由器主要采用FAT胖AP的形式完成,将有线网络信号转换为无线网络信号,为移动设备提供联网服务
WLAN企业、园区网络应用
- 企业无线局域网主要采用FITAP架构模式,华为等多种品牌的部分AP均支持胖、瘦、云AP三种工作模式,根据实际情况可以灵活切换
- 目前大多数设备均支持POE(Power Over Ethernet,以太网供电)供电模式,即通过网线进行电源传输,不过在使用POE供电模式中,
建议使用高类别的
AC的连接方式
AC的连接方式
- 直连式组网
- AP和AC直连上层网络,形成一个串联的网络结构
- 所有无线数据都必须经过AC转发,这种方式更有助于让AC进行AP的流量集中管理
- 旁挂式组网
- AC不用连接到上层网络,而是通过AP与网络相连接
- AC主要负责处理不同AP的数据,进行AP的管理
- AP直接将数据发给上层路由器进行联网操作
CAPWAP协议
- CAPWAP(Control And Provisioning of Wireless Access Points Protocol):无线接入点控制协议
- 定义了如何对AP进行管理、配置,也就是AC通过CAPWAP来管理AP设备
- 具体功能是AP和AC的状态维护,AC通过CAPWAP隧道对AP进行管理、配置
SSID
- 服务集标识符(Service Set Identifier)
- 是无线网络的一个身份标示,使用字符串表示
- 为了方便用户识别不同的无线网络,使用SSID来替换了BSSID
VAP
- 虚拟访问点(Virtual Access Point)
- 就是在一个物理的AP上虚拟出多个AP,每个被虚拟出来的AP就是VAP,并且与AP提供的功能是一样的
- 每个VAP对应一个BSS,这样一个AP就可以提供不同的BSS,设置不同的SSID,区分出网络范围
WLAN 配置四步模板(华为 AC)
- 基础配置(VLAN + 接口 + DHCP)
- vlan 100 # 业务VLAN
- vlan 101 # 管理VLAN
- int Vlanif100
- ip add 192.168.100.254 24
- dhcp select global
- int Vlanif101
- ip add 192.168.101.1 24
- dhcp select interface
- int g0/0/1
- port link-type trunk
- port trunk allow-pass vlan all
AC 上线配置
- capwap source interface Vlanif101 # 指定AC源接口
- wlan
- ap-id 0 ap-mac 00e0-fc12-3456 # 绑定AP
- ap-name AP1
- ap-group ap-group1
安全模板(Wi-Fi 密码)
- security-profile name SEC
- security wpa2 psk pass-phrase Huawei@123 aes
SSID 模板
- ssid-profile name SSID
- ssid Huawei-WiFi
VAP 模板(绑定模板 + VLAN)
- vap-profile name VAP
- forward-mode tunnel
- service-vlan vlan-id 100
- security-profile SEC
- ssid-profile SSID
AP 组调用 VAP
- ap-group ap-group1
- vap-profile VAP wlan 1 radio 0 # 2.4G
- vap-profile VAP wlan 1 radio 1 # 5G
查看命令
- display ap all # 查看AP是否上线(normal正常)
- display vap all # 查看Wi-Fi状态
- display ap address # 查看AP地址
二十二、QOS
QoS的三个服务模型
- 1、尽力而为模型
- 1)完全遵守流量的先来先走的原则,没有任何优先级而言,是相对公平的处理流量的方式
- 2)尽可能的传递所有需要传输的数据,无法保证网络低延迟以及稳定性
- 2、综合服务模型
- 1)提前预留流量资源,剩下流量均匀分配给其他普通业务
- 2)当特定流量经过时,使用预留的流量,保证特定业务的稳定性
- 3)可以保证某些流量的带宽,但是会浪费一部分的网络资源
- 3、区分服务模型
- 1)提前预留流量资源,当特定的流量没有经过时,所有业务均分所有流量
- 2)当特定流量经过时,优先传递特定流量
- 3)不会浪费带宽,并且区分流量的优先级
QoS流量管理方式
- 1、流量监管
- 1)将所有超出的流量全部丢弃
- 2)减少网络设备的工作压力,延迟比较低,但是丢包率比较高
- 3)在实时流量如UDP中的各项协议使用较多
- 2、流量整形
- 1)将超出的流量进行缓存,当有足够的“令牌”时进行有序传输
- 2)丢包率比较低,可以保证数据的稳定传输,但是网络设备的工作压力较大,延迟较高
- 3)在TCP各项协议中使用的较多
QoS的设置方式
- 1、基本QoS
- 1)无法针对流量进行区分,所有流量全部进行限制
- 2)灵活性比较差
- 2、基于类的QoS
- 1)通过 ACL 进行流量限制,针对不同区域的网络设置不同的QoS控制
- 2)可以有针对性的进行操作管理
- 3)执行步骤
- 1. 创建流分类:通过绑定预设好的 ACL 进行流量分类
- 2. 创建流行为:具体限制的内容,比如使用car还是gts,限制的数值是多少
- 3. 创建流策略:将创建的流分类和行为进行绑定
- 4. 应用流策略:进入到对应的接口中应用策略
基于类 QoS 配置模板
- 配置 ACL 匹配流量
- acl 2001
- rule permit source 192.168.1.0 0.0.0.255
- 配置流分类
- traffic classifier CLASS1
- if-match acl 2001
- 配置流行为(限速)
- traffic behavior BEHAVE1
- car cir 10000 cbs 150000
- 配置流策略
- traffic policy POLICY1
- classifier CLASS1 behavior BEHAVE1
- 接口应用策略
- interface g0/0/1
- traffic-policy POLICY1 inbound
简单 QoS(直接接口限速)
- interface g0/0/1
- qos car outbound cir 5000
- qos gts cir 5000
查看命令
- display traffic classifier
- display traffic behavior
- display traffic policy
- display traffic policy interface
二十三、IPsec VPN
IPsec(IP Security)
- 工作在网络层的安全协议,用于在公网(互联网)上建立加密隧道,实现:
- 数据加密
- 身份认证
- 数据完整性
- 防重放攻击
- 常用于企业总部 — 分支互联、远程办公加密。
互联网中的加密方式
- 1)对称加密
- 1. 缺点:
- a. 双方共享一个秘钥,如果其中任意一方丢失或者被攻击破解,则整个网络具有安全隐患
- b. 加密效果较差,被破解的可能性较大
- 2. 优先:
- a. 加密速度快,占用设备的性能少
- 2)非对称加密
- 1. 缺点:
- a. 加密过程复杂,速度较慢,占用设备性能较大
- 2. 优先:
- a. 通过公钥、私钥进行加密解密,将公钥放到互联网上,其它用户通过公钥加密数据,自身接收到后通过自己的私钥解开数据
- b. 加密效果更佳,被破解几率更小
- c. 发送数据前通过私钥进行数据签名,保证了数据的不可否认性
VPN协议分类
- 按层次(重点)
- 二层隧道协议:PPTP、L2TP、L2F
- 三层隧道协议:IPSec、GRE
- 按用途
- Intranet VPN:企业内部(总部↔分支)
- Extranet VPN:企业与合作方
- Access VPN:远程办公 / 移动用户
IPsec 核心组件
- AH 协议(认证头)
- 协议号:51
- 提供:认证、完整性、防重放
- 不加密数据
- ESP 协议(封装安全载荷)
- 协议号:50
- 提供:加密 + 认证 + 完整性
- 实际工作中最常用
- IKE 协议(Internet 密钥交换)
- 自动协商密钥、建立 SA(安全关联)
- 简化配置,不用手动设密钥
- SA(Security Association 安全关联)
- IPsec 的安全连接
- 单向,包含:加密算法、认证算法、密钥、生命周期
- 双向通信需要 两个 SA
IPsec 两种工作模式
- 传输模式(Transport Mode)
- 只加密数据部分,不加密原 IP 头
- 用于:主机 ↔ 主机
- 不能跨 NAT
- 隧道模式(Tunnel Mode)
- 对整个原始 IP 包加密,再封装新 IP 头
- 用于:网关 ↔ 网关(企业 VPN)
- 支持 NAT,实际工程 100% 使用
IPSec主要通过两个协议保证数据安全
- 认证头(AH):这是一种安全协议,用于保证数据包的完整性和验证数据的来源,同时也可以防止重放攻击。使用的是51端口
- 封装安全载荷(ESP):这个协议用于加密数据包的内容,确保数据的机密性,并提供数据源认证以及防止重放攻击。使用的是50端口
IPsec 工作流程
- ACL 触发:定义需要保护的流量
- IKE 阶段 1:建立管理连接,认证身份、协商密钥
- IKE 阶段 2:建立 IPsec SA,协商加密方法
- 数据加密传输:ESP/AH 封装加密转发
IPsec 配置五步模板
- 配置 ACL(定义要保护的流量)
- acl 3000
- rule permit ip source 192.168.1.0 0.0.0.255 destination 192.168.2.0 0.0.0.255
- 配置 IPsec 安全提议(加密方式)
- ipsec proposal prop1
- esp encryption-algorithm aes-256
- esp authentication-algorithm sha1
- 配置 IKE 提议(IKE 加密算法)
- ike proposal 1
- encryption-algorithm aes-256
- authentication-algorithm sha1
- dh group14
- 配置 IKE 对等体(对方 IP、预共享密钥)
- ike peer peer1
- pre-shared-key simple Huawei@123
- ike-proposal 1
- remote-address 202.100.1.1
- 配置 IPsec 策略并应用到接口
- ipsec policy policy1 10 isakmp
- security acl 3000
- proposal prop1
- ike-peer peer1
- interface g0/0/1
- ipsec policy policy1
查看命令
- display ike sa 查看 IKE 安全关联
- display ipsec sa 查看 IPsec 安全关联
- display ipsec policy 查看 IPsec 策略
必背核心结论
- IPsec = 三层加密 VPN,用于企业跨公网安全通信
- ESP 加密 + 认证;AH 只认证不加密
- 隧道模式用于网关,支持 NAT;传输模式用于主机
- IKE 自动协商密钥,SA 是单向安全连接
- 配置顺序:ACL → 提议 → IKE 对等体 → 策略 → 接口调用
二十四、DHCP
数据链路层三大安全威胁
- MAC 地址表溢出攻击
- 原理:攻击者发送大量虚假 MAC 地址,填满交换机 MAC 表,导致新设备无法学习,流量变广播,信息泄露。
- 防御:端口安全(Port Security)
- ARP 欺骗 / 攻击
- 原理:发送伪造 ARP 报文,篡改 IP 与 MAC 对应关系,实现中间人窃听、断网。
- 防御:静态 IP+MAC 绑定、ARP 安全、DHCP 监听
- DHCP 攻击
- DHCP 地址耗尽:疯狂发送 DHCP 请求,占满地址池,合法用户无法上网。
- DHCP 服务器欺骗:伪造 DHCP 服务器,分配恶意网关、DNS,劫持流量。
- 防御:DHCP Snooping(DHCP 监听)
内网中出现的安全隐患
- MAC地址表震荡
- ARP攻击
- ARP欺骗
- DHCP地址池耗尽
- DHCP欺骗
MAC地址溢出
- 其中某个客户机大量的向交换机发送mac地址,导致交换机中的mac地址表饱和,新的mac地址无法学习,导致溢出
- 如果这时有新的数据请求转发,这无法学习,并且这个数据包被广播的方式发出
- 导致数据被篡改或者丢失
ARP攻击
- 由于ARP特殊的工作原理,可能会被利用漏洞进行攻击
- 客户端将错误的MAC地址发送给核心设备,导致数据无法传递到真实的目的地址,导致数据的泄露或者丢失
- 如果攻击的是网关设备则导致整个内网环境无法通信
dhcp服务欺骗和地址耗尽
- 客户机通过脚本程序大量的向服务器发送discovery发现包,请求DHCP服务器的位置以及IP地址
- 导致DHCP服务器的地址池中的所有地址被占用,真实客户机无法获取IP导致无法上网
- 这时攻击者通过创建虚假的DHCP服务回应客户机的discovery包,向服务机发送offer报文
- 可能导致数据泄露或者流量被转发到其他网络中
端口安全 Port Security
- 作用
- 限制端口学习 MAC 地址数量,防止 MAC 泛洪攻击。
- 配置命令(一行一条 + 作用)
- port-security enable #作用:开启接口端口安全
- port-security max-mac-num 2 #作用:设置端口最大学习 MAC 数量为 2
- port-security aging-time 300 #作用:设置 MAC 老化时间 300 秒
- port-security protect-action shutdown #作用:违规时端口关闭(最严格)
- port-security protect-action restrict #作用:违规丢弃报文、记日志
- port-security protect-action protect #作用:违规仅丢弃报文
- error-down auto-recovery cause port-security interval 60 #作用:违规自动恢复时间 60 秒
DHCP 监听 DHCP Snooping
- 作用
- 防止 DHCP 欺骗
- 防止 DHCP 地址耗尽
- 信任端口只给合法 DHCP 服务器
- 端口两类角色
- 信任端口(Trusted)
- 接合法 DHCP 服务器、上联交换机
- 允许所有 DHCP 报文(Offer、ACK)
- 非信任端口(Untrusted)
- 接 PC、终端
- 只允许发 Discovery、Request 报文
- 配置命令
- dhcp enable #作用:开启 DHCP 功能
- dhcp snooping enable ipv4 #作用:全局开启 DHCP 监听
- dhcp snooping check dhcp-rate enable #作用:开启 DHCP 报文速率限制
- dhcp snooping check dhcp-rate 50 #作用:每秒最多允许 50 个 DHCP 报文
- interface g0/0/5
- dhcp snooping trusted #作用:设置接口为信任端口(接 DHCP 服务器)
- interface g0/0/1
- dhcp snooping enable #作用:接口开启 DHCP 监听
- dhcp snooping max-user-number 10 #作用:接口最多允许 10 个 DHCP 用户
- display dhcp snooping global #作用:查看 DHCP 监听状态
DHCP 服务器配置(两种模式)
- 接口模式 DHCP(简单)
- dhcp enable
- interface g0/0/1
- ip address 192.168.10.1 255.255.255.0
- dhcp select interface
- dhcp server dns-list 114.114.114.114
- dhcp server excluded-ip-address 192.168.10.200 192.168.10.254
- 全局地址池模式(最常用)
- dhcp enable
- ip pool vlan10
- network 192.168.10.0 mask 255.255.255.0
- gateway-list 192.168.10.1
- dns-list 114.114.114.114
- excluded-ip-address 192.168.10.200 192.168.10.254
- interface g0/0/1
- dhcp select global
整体防御总结
- MAC 溢出 → 端口安全(限制 MAC 数量)
- ARP 攻击 → IP+MAC 静态绑定
- DHCP 欺骗 / 耗尽 → DHCP Snooping
- 下联口 = 非信任;上联 / DHCP 服务器 = 信任
- DHCP 两种配置:接口模式、全局地址池
- 跨网段分配地址 → DHCP 中继
二十五、防火墙
防火墙是什么
- 位于内外网之间的安全设备,负责访问控制、攻击防护、流量过滤。
- 核心:按规则允许 / 拒绝流量,保护内网安全。
- 与路由器、交换机区别:
- 交换机:二层转发,MAC 寻址
- 路由器:三层选路,IP 寻址
- 防火墙:安全检查,区域隔离,策略控制
目前常见的网络设备的厂商
- 华为,H3C(华三),思科,锐捷,深信服,天融信
防火墙
- 软件防火墙,在系统上使用,硬件防火墙,部署在网络的节点上,防止两个网络之间传输危险的数据、程序
防火墙与路由器的区别
- 防火墙在转发数据时更复杂,会检查数据包中的详细内容,具有数据转发的功能,但是主要完成的是保证了数据的安全性
- 路由器主要是查看数据包的IP地址属性,找到最优的路线,完成最快的转发
防火墙三个重要的概念
- 四个安全区域
- local:本地区域,优先级是100,用在设备的本身
- trust:信任区域,优先级是85,用在办公网络中
- DMZ:非军事化区域,优先级是50,用在服务器网络中
- untrush:非信任区域,优先级是5,连接公共网络(Internet)
- 优先级数字越大越安全。
- 默认:高优先级 → 低优先级 允许;低→高 默认拒绝。
- 默认区域不能删、不能改优先级。
- 区域的特点
- 默认的四个区域无法删除、修改优先级
- 默认高优先级的区域可以通过低优先级的区域
- 安全策略
- 防火墙主要是依靠安全策略进行网络安全的限制
- 首先匹配条件,然后查看动作
- 条件:源目的的地址和端口以及区域以及服务名称
- 动作:deny和permit
- 防火墙中有一个默认的default策略,优先级最低,条件是any,动作是deny
会话表
- 存储通过防火墙的每一条流量,仅需要针对首包或者部分数据包进行检查过滤即可
- 加快的数据包收发的速度,并且减少了设备的资源占用
- 加快的数据包收发的速度,并且减少了设备的资源占用
- FTP一般用于下载上传文件,所有老化时间默认为10分钟
- 其他协议为较少,单位为秒
防火墙过滤数据的具体流程是
- 接收数据包,作进一步的处理
- 匹配会话表,如果成功则直接转发,如果失败则查看策略
- 允许则创建会话然后转发,否则丢弃
- 对端回应数据查看会话条目,存在则通行,否则拒绝
接口加入区域
- firewall zone trust
- add interface GigabitEthernet 1/0/1
- firewall zone dmz
- add interface GigabitEthernet 1/0/0
- firewall zone untrust
- add interface GigabitEthernet 1/0/2
安全策略
- 作用
- 控制哪个区域 → 哪个区域的流量能通。
- 匹配条件(五元组)
- 源区域 / 目的区域
- 源 IP / 目的 IP
- 服务(TCP/UDP/ICMP/FTP/HTTP 等)
- 时间段、用户、应用
- 动作
- permit 允许
- deny 拒绝
- 匹配规则
- 从上往下匹配
- 匹配一条就不再往下匹配
- 最后默认策略:全部拒绝 deny
安全策略配置模板
- security-policy
- rule name trust_to_dmz
- source-zone trust
- destination-zone dmz
- source-address 192.168.2.0 mask 255.255.255.0
- destination-address 10.0.0.0 mask 255.0.0.0
- service icmp
- service ftp
- action permit
- rule name trust_to_untrust
- source-zone trust
- destination-zone untrust
- service icmp
- action permit
常用必备命令
- 区域配置
- firewall zone trust
- add interface g1/0/1
- 安全策略
- security-policy
- rule name xxx
- source-zone trust
- destination-zone dmz
- service icmp
- action permit
- 查看会话
- display firewall session table
- 查看区域
- display zone
- 查看策略
- display security-policy rule all
- 开启服务访问(ping/http/https)
- interface g1/0/1
- service-manage ping permit
DHCP + 安全区域 + 策略 典型结构
- 内网接口 → Trust
- 服务器区 → DMZ
- 外网接口 → Untrust
- 策略:
- Trust → DMZ:允许业务
- Trust → Untrust:允许上网
- Untrust → 所有区域:默认拒绝
- DMZ → Untrust:允许服务器上网
双机热备的要求
- 硬件要求
- 组成双机热备的两台FW的型号必须相同,安装的单板类型、数量以及单板安装的位置必须相同。
- 两台防火墙的硬盘配置可以不同
- 软件要求
- 组成双机热备的两台FW的系统软件版本、系统补丁版本、动态加载的组件包、特征库版本、HASH选择CPU模式等必须相同
- License要求
- 双机热备功能自身不需要License。
- 但对于其他需要License的功能,如IPS、反病毒等功能,组成双机热备的两台FW需要分别申请和加载License,两台FW之间不能共享License。两台FW的License控制项种类、资源数量、升级服务到期时间都要相同。
- 双机热备具有配置同步的功能
双机热备工作模式
- 主备备份模式
- 两台设备一主一备。正常情况下业务流量由主用设备处理。当主用设备故障时,备用设备接替主用设备处理业务流量,保证业务不中断。
- 负载均衡模式
- 两台设备互为主备。正常情况下两台设备共同分担整网的业务流量。当其中一台设备故障时,另外一台设备会承担其业务,保证原本
通过该设备转发的业务不中断。
远程网络设备方式
远程网络设备方式
- 1、使用的协议
- 1)telnet:使用 23 端口,数据传递时没有加密功能
- 2)Stelnet:使用 SSH 协议的 22 端口,使用“公加私解”的加密功能
- 2、认证模式
- 1)password:是默认的认证模式,仅需要输入密码即可,无法针对不同的连接成员做不同的权限管理
- 2)AAA:需要创建用户,可以针对每个用户设置不同的权限级别
- 3、级别
- 1)范围是 0 - 15 范围,数值越高级别越大,默认的级别是 0
- 1. “0” 表示最基本的权限,仅可以进入做一些测试命令
- 2. “1” 监控级别,仅可以查看部分信息
- 3. “2” 管理级别,可以做大多数的操作管理
- 4. “3-15” 高级管理员,可以做所有的配置部署
linux安装系统
linux的优点
linux的优点
- 稳定性强,可以长时间运行并且不会出现任何故障
- 安全性高,漏洞比较少,被攻击的可能性较低
- 资源占用率低,性价比高,运行速度快
- 开源
虚拟机仅主机模式与 NAT 模式核心区别
- 两者的核心差异在于 虚拟机能否访问外网、网络通信范围
- 仅主机:虚拟机只和「宿主机(你的电脑)」互通,虚拟机之间也能互通,但 虚拟机完全不能访问外网
- NAT:虚拟机通过宿主机的网络「间接访问外网」,虚拟机之间、虚拟机与宿主机也能互通,外网无法直接访问虚拟机
Linux中的默认目录
- 1)Linux存储结构全部都是以 “/” 开始
- 2)"/"上常用的存储目录
- -/bin = 存放基本命令(所有用户均可以执行的命令文件)(ls、cp、mv等)
- -/sbin =存放系统管理命令(系统管理员可以执行的命令文件)(fdisk、ifconfig等)
- - /dev = 存储系统所有硬件的信息
- - /home = 存储普通用户的宿主目录
- - /root = root用户的宿主目录
- - /etc = 存储系统关键文件
- - /boot = 存储系统引导程序以及一些必要加载项
- - /var/log = 存储系统日志文件
- -/usr/bin=存放用户应用程序命令(gcc、perl等)
- -/user/sbin=存放系统管理命令和程序(mysqld、httpd等)
- -/proc=特殊的虚拟文件系统(以直接查看内核的运行状态,读取系统 / 进程的实时数据,获取硬件信息)
Linux硬盘文件的表示方法
- 1)主机硬盘分为两个接口模式
- 1. scsi 是服务器目前最常见的接口类型,如果是此类接口,则以 sd 表示
- 2. ide 接口是早期硬盘接口,目前几乎淘汰,如果是此类接口,则以 hd 表示
- 2)计算机每块硬盘使用字母 a - z 表示,假如使用 scsi 接口的第一个硬盘则表示为 sda,第二个则表示sdb,第五个则表示sde
- 3)硬盘文件完成后,在进行系统安装时会对现有整个硬盘进行分区处理
- 1. 使用MBR类型进行分区最多可以有四个主分区,分别占用1 - 4分区号
- a. 主分区:系统安装完成后只有主分区可以创建系统引导记录
- b. 扩展分区:占用一个主分区号,无法直接使用,需要在扩展分区中创建逻辑分区进行数据存储使用
- c. 逻辑分区:分区号永远从 5 开始,仅作为数据存储分区,无法启动系统,数量没有限制,最大容量是扩展分区的最大值
- 2. 使用 GPT 类型则可以创建 128 个主分区
- 4)练习:
- 1. ide 接口中的第二个硬盘的第一个主分区: hdb1
- 2. scsi接口中的第一个硬盘的第一个逻辑分区:sda5
- 3. sdc7 : scsi 接口的第三个硬盘的第三个逻辑分区
- 4. hdd2 : ide 接口的第四个硬盘第二个主分区
文件系统类型
- 1)文件存储类型主要分为两种
- 1. ext:CentOS 7 之前版本的默认文件类型,存储小文件功能较好,目前最新版是 ext4
- 2. xfs:CentOS 7 新推出的系统类型,并且也是默认的类型,存储大文件功能较高
- 2)交换分区文件类型(虚拟内存,也叫交换内存)
- 1. swap:Linux系统中的虚拟内存,缓解物理内存的工作压力,并且提高系统的运行速度,一般虚拟内存的数量是物理内存的 2 倍
- 3)Linux还支持windows系统中的文件系统
- 1. NTFS、FAT32 ..
安装后必要配置(临时,系统重启后需要再次操作)
- 1)针对防火墙进行管理
- iptables -F #清空防火墙中的所有条目,影响通信
- systemctl stop firewalld
- systemctl disable firewalld #开机不会启动防火墙
- 2)关闭 selinux
- setenforce 0
Linux系统启动级别,每个级别表示不同的功能,总共分 0 - 6,7个级别
- 1)常见级别
- 0 = 关机状态,无法设置为默认
- 1 = 单用户无网络连接模式的字符界面,一般用于紧急系统维护
- 2 = 多用户无网络连接模式的字符界面,同样用于紧急维护
- 3 = 多用户网络连接模式的字符界面,生产环境下最常用的模式
- 4 = 保留未使用
- 5 = 多用户桌面环境
- 6 = 重启状态,无法设置为默认
- 2)级别之间切换使用 init 命令
- init [ id ]
系统服务控制命令
- 1)命令字 systemctl
- 2)动作
- stop 停止
- start 打开
- restart 重启
- reload 重新加载
- status 查看状态
- 3)操作的对象 firewalld、network、httpd、dhcpd ... ... ...
- 4)语法:
- systemctl [ 动作 ] [ 对象 ]
针对系统服务进行控制的命令,使用命令管理服务开机启动的服务
- 1)批量化管理
- 1. ntsysv [ --level 级别 ] #级别是可选的,默认针对所有级别
- 2)单一管理,核心命令字是 chkconfig
- 1. 查看某个服务的启动级别
- chkconfig --list [ 服务名称 ]
- 2. 管理级别
- chkconfig --level [ 级别 ] [ 服务名称 ] off/on
- 3.添加服务
- chkconfig --add [服务名称]
命令
- shutdown now 关闭虚拟机 traceroute 服务 路由跟踪
Linux基本命令
路径
路径
- 绝对路径
- 永远是从“/”目录为起点
- 相对路径
- 永远是从当前路径为起点
基本命令
- 1、mkdir #创建目录
- -p #递归创建
- -v #显示结果
- ps:
- mkdir -p /qm/{T1,T2,T3} #递归创建,并且同时创建多个平级目录
- 2、mv #移动文件、目录(移动时可以进行重命名)
- 3、pwd #查询当前用户所在位置
- 4、touch #创建文件
- 5、cp #复制文件 (复制的时候也可以进行重命名)
- -r #复制目录
- -p #保留源文件属性
- -f #强制复制,就是会自动覆盖
- -a #递归复制不遗漏、权限属性全保留、软链接不失效
- 6、cd #切换路径
- .. #返回上一级
- - #返回上一次的目录位置
- ~ #表示用户的宿主目录
- #直接回到当前用户的宿主目录
- 7、ls #查看目录中的文件信息
- -l #以长格式展示(其中第一个字符是d表示目录,第一个字符为-则表示文件)
- -a #显示隐藏内容
- -d #只显示目录本身,不列出目录内的内容
- 8、rm #删除文件
- -r #允许删除目录
- -f 删除时不提示信息
- 9、su #切换用户
- 10、服务 -t #可以验证是否正常启动,验证服务的配置文件是否编写错误
- 11、curl IP #验证httpd服务,会显示出index文件里的内容也就是网页的内容
- 12、free #查看内存使用情况
- -h #以人性化的方式显示
- available #表示当前真正可以分配给新进程的内存大小
- 13、uname -r #查看系统内核版本
- 14、lscpu #查看系统CPU核数
- 15、find /var/log -name "*.log" -mtime -7 -delete #查找/var/log下七天内修改过的文件并删除
- -mtime -7:7 天以内修改过的文件
- -mtime +7:7 天以前修改过的文件
- -delete:直接删除
- -name:设置查找的文件名
- -type f:查找类型为文件
- d查找类型为目录
- 16、systemctl list-unit-files --type=service #查看开机自启服务的命令
- systemctl is-enabled nginx #查看某个服务是否开机自启(比如 nginx)
- 17、hostname #查看主机名
- hostname test-server #临时修改主机名(重启失效)
- hostnamectl set-hostname test-server 或修改/etc/hostname #永久修改主机名(重启依然生效)
- 18、cat /etc/os-release #查看系统发行版(CentOS / Ubuntu 都能用)
- cat /etc/redhat-release #专看 CentOS/RHEL 版本
- 19、du -sh 目录 #查看目录或文件的大小
- -s 只显示总计大小,不会把目录下的文件大小显示出来,只显示目录的总大小
- -h 人类易读格式
- 20、env #查看系统所有环境变量
- echo $PATH #查看某个具体的环境变量?比如查看 PATH
- 21、which #查找命令的可执行文件所在路径
- 22、uptime #查看系统负载
- 系统负载和CPU使用率的区别:只算正在运行的进程(CPU) 运行中 + 排队等待的进程(负载)
- 23、sort #排序
- sort # 字符正序,会把重复的排在一起
- sort -n # 纯数字排序
- sort -nr # 数字倒序(高频)
- sort -u # 自动去重
- 24、uniq #去重 + 计数(必须先 sort),只能去重相邻行
- uniq -c # 统计重复次数(最常用)
- uniq -d # 只显示重复行
- 25、cut #精准切割字符 / 分隔符
- cut -d ":" -f1 # 以冒号分割,取第1段
- cut -c 1-5 # 截取第1到5个字符
- 26、wegt #网络下载工具:从网络地址 下载单个文件、安装包、网页,命令行直接输网址就能下载,只做单纯下载
- 27、git #分布式版本控制工具:管理代码、记录代码每一次修改,多人协作开发、回退版本、分支开发
- 拉取代码仓库、提交代码、托管项目(GitHub/Gitee)
- git init:初始化本地仓库
- git clone:克隆远程仓库到本地
- git add:把文件加入暂存区
- git commit:提交暂存内容到本地仓库
- git push:推送本地代码到远程仓库
- git pull:拉取远程最新代码到本地
- git branch:查看 / 创建分支
- Git 工作区、暂存区、本地仓库、远程仓库的关系
- 工作区:本地实际开发写代码的目录,肉眼能看到文件。
- 暂存区:临时存放要提交的改动,git add 就是把代码放到暂存区。
- 本地仓库:.git 隐藏目录,保存历史版本快照,git commit 把暂存区代码提交到本地仓库。
- 远程仓库:云端仓库(GitHub/GitLab),用于多人协作、备份代码,git push 推送、git pull 拉取
- 28、lsof -i:端口号 #查看某个端口被哪个进程占用
Linux系统设置IP地址
- 1、临时修改:系统重启之后消失
- ifconfig ens33 { ip地址 } [ 掩码(无类地址时使用) ]
- 2、永久修改:修改网卡配置文件,永久性生效
- vim /etc/sysconfig/network-scripts/ifcfg-ens33
- BOOTPROTO=static #将原来的 dhcp 改为 static
- ONBOOT=yes #将原来的 no 改为 yes
- IPADDR=192.168.56.11 #添加新的条目,指定IP地址
- PREFIX=24 #添加新的条目,指定掩码
- NETMASK=255.255.255.0 #指定掩码,与PREFIX功能一样,二选一
- GATEWAY=192.168.56.54 #添加网关
- systemctl restart network #重新启动 network 服务,重新读取文件中的数据,获取新的IP
linux命令格式:命令字 [选项] [参数]
- 命令字:在一行代码中只能存在一个命令字符,决定了这条指令的具体工作内容
- 选项:设置当前命令具体功能,分成两种格式
- 长格式:“--”表示,后面跟选项
- 短格式:“-”表示,短格式可以写在一起省略 “-” 符号
- 参数:当前命令具体要操作的对象,一般是用户、服务文件或者目录
管道符和重定向
- “|” 管道符之前的内容不输出到终端而是交给后面的指令继续执行
- > 将输出的内容以替换方式写入到指定文件中
- >> 将输出的内容以追加方式写入到指定文件中
查看命令
- cat:查看文件中的内容(当文件内容比较少时使用,会直接将文件中的所有内容全部展示出来)
- more:全屏显示文件内容(无法上下移动,允许使用回车键翻页)
- less:与more功能类似,但是功能更强大(允许上下移动,且加载速度比more快)
- head:默认查看前10行内容,可以通过 -2选项仅显示前2行
- tail:默认查看后10行内容,可以通过 -2选项仅显示后2行
统计命令
- wc:统计文件中的信息,如果不加选项则统计全部信息
- -l:统计行数 -w:统计单词数 -c:统计字节数
过滤文件内容
- grep:在文件中查找指定的字符的行
- -i:查找时忽略大小写 -v:反向查找,输入的内容与查找内容相反
- "^root":查找root开头的行 " root$ ":查找root结尾的行
- " ^$ ":查找空行
tar:制作归档文件
- c:创建 .tar 格式的包文件 x:解开 .tar 格式的包文件
- v:输出详细信息 f:表示使用归档文件
- p:打包时保留原始文件及目录的权限
- t:列表查看包内的文件 -C:解包时指定释放的目标文件夹
- z:调用gzip程序进行压缩或解压 j:调用bzip2程序进行压缩或解压
vi 编辑器
- 作用:创建以及修改Linux文件内容
- vim是vi编辑工具的升级版,功能性更强,精简版安装默认没有vim命令,需要手动安装
- vi 默认有三个模式
- 命令模式
- 进入后默认的模式
- 可以使用各种命令进行文本管理
- 编辑模式(输入模式)
- 对文本进行编辑
- 末行模式(底线模式)
- 可以对文本进行保存退出、文本替换等功能
- 模式间转换
- 命令模式下输入
- i = 进入编辑模式
- a = 跳转到光标下一个字符进入编辑模式
- o = 创建一个空行并且跳转进入编辑模式
- := 进入末行模式
- / = 进入末行模式
- 编辑模式:
- ESC = 回到命令模式
- 末行模式:
- ESC = 回到命令模式
- 只可以通过命令模式跳转到其他模式中
- 命令模式下的命令
- 行内跳转
- G = 跳转末行
- gg = 跳转行首
- 20G = 跳转到20行
- 删除
- dd = 删除当前行
- 3dd = 删除光标向下三行
- D = 删除当前光标后面的字符
- 粘贴复制
- yy = 复制当前行
- 3yy = 向下复制三行
- P = 向上粘贴(大写)
- p= 向下粘贴
- 撤回
- u=撤回上一步
- 末行模式下的命令
- set nu = 显示行号
- set nonu = 关闭行号显示
- /data = 从上到下查找data字符,n向下查找,N向上查找
- :w = 保存
- :wq = 保存退出
- :q = 直接退出
- :q! = 强制退出
- :wq!= 强制保存退出
- :s /old/new/g = 将当前行所有old替换成new
- :10,15 s/old/new/g = 10-15行中的old换成new
- :% s/old/new/g = 全文old换成new
程序安装及管理
软件包封装类型
软件包封装类型
- rpm软件包:是一种基于Red Hat Package Manager(RPM)的Linux软件包格式,用于安装、升级和卸载软件。后缀名为.rpm
- 源代码软件包:是指包含源代码的软件包,用户可以根据自己的需求对源代码进行编译和安装。后缀名一般使用tar包结合压缩软件打包.tar.gz
或者 .tar.bz2
RPM包管理工具
RPM包管理工具
- -qa:查看系统中已安装的所有RPM软件包列表
- -qi:查看指定软件的详细信息
- -ql:查询指定软件包所安装的目录、文件列表
- -qc:仅显示指定软件包安装的配置文件
- -qd:仅显示指定软件包安装的文档文件
- -qf:查看某个文件或者目录是通过那个软件包安装的
升级、安装、卸载软件包
- -i:安装一个新的 rpm 软件包
- -U:更新软件包时需要首先安装完成依赖包,否则无法更新
- -F:强制更新某个软件包,不解决依赖关系,可能造成软件稳定性差的问题
- -e:卸载一个软件包
- --force:强制安装所指定的rpm软件包
- --nodeps:安装、升级或卸载软件时,忽略依赖关系
- -h:以“#”号显示安装的进度
- -v:显示安装过程中的详细信息
yum的概念
- yum仓库分为两种:本地yum和网络yum,yum仓库中存放着大量的rpm包,使用yum安装时就是调取这些rpm包安装到系统
- yum仓库中有一个类似表格的文件,后缀名是*.xml,存储着所有rpm包的信息,使用yum完成安装时,调取这个表格中每个rpm包信息,
如果有捆绑的依赖关系,则直接将所有的依赖软件进行安装
- 检验yum仓库是否生效的命令:清理原有 yum 缓存:yum clean all
- 生成新缓存并验证:yum makecache(如果能成功生成缓存,说明本地源生效)
- 也可以尝试安装一个文件看看yum的来源是哪里
配置 yum 仓库有的主要文件有两种方式
- 1)将所有文件删除,然后手写文件内容
- 1. mount /dev/cdrom /media #挂载 iso 文件,使系统具备 rpm 包
- 2. rm -rf /etc/yum.repos.d/* #删除所有 yum 配置文件
- 3. vim /etc/yum.repos.d/abc.repo #创建 yum 配置文件
- [haha] #yum仓库当前区域名称,名称随意
- name=hhhh #当前区域名称,名称随意
- baseurl=file:///media #指定本地系统 rpm 包存放目录
- gpgcheck=0 #是否检查每个 rpm 包,0表示不检查,1表示检查
- enabled=1 #是否开启 yum 仓库,0表示关闭,1表示开启
- 2)删除网络 yum 文件,修改本地 yum 文件(yum工具首先查看网络yum文件)
- 1. mount /dev/cdrom /media #挂载 iso 文件,使系统具备 rpm 包
- 2. cd /etc/yum.repos.d/ #进入到 yum 配置文件的目录中
- 3. rm CentOS-Base.repo #删除网络 yum 配置文件
- 4. vim CentOS-Media.repo #使用 vi 编辑器进入到本地 yum 配置文件中
- [c7-media] #yum仓库当前区域名称,名称随意
- name=CentOS-$releasever - Media #当前区域名称,名称随意
- baseurl=file:///media #指定本地系统 rpm 包存放目录
- gpgcheck=0 #是否检查每个 rpm 包,0表示不检查,1表示检查
- enabled=1 #是否开启 yum 仓库,0表示关闭,1表示开启
- 3)使用 yum 工具安装、卸载软件
- 1. yum -y install [ 服务名称 ] #安装服务
- yum -y install httpd #安装 httpd 服务
- yum -y install dhcp #安装 dhcp 服务
- 2. yum -y remove [ 服务名称 ] #卸载服务
源代码编译安装
- 安装源码包环境必须的软件
- (gcc-c++-4.8.5-39.el7(用于解析源码包中的 C 语言)
- make-3.82-24.el7.……(将 C 语言编译为二进制文件,并且安装到系统
- pcre* apr*)
- 将源码包进行解压,一般源码包为格式为*.tar.gz或者*.tar.bz2(通过其他途径将源码包放入到linux-centos7中)
- 进入解压后的目录中输入:./configure --prefix=安装路径 (其中--prefix为指定安装路径)
- 安装完成后输入 make(将源代码(C语言)编译为二进制语言)
- 然后继续输入 make install(将编译完成的二进制代码安装到系统) 安装软件
- 最终后设置
- PS:httpd服务使用/usr/local/httpd/bin/apachectl start 来开启,并且重启系统也要重启服务
账号和权限管理
Linux系统创建用户整体流程
Linux系统创建用户整体流程
- 1)创建用户指定宿主目录后
- 1. 系统自动创建宿主目录,前提需要保证上级目录的存在
- 2. 如果使用非 root 用户创建的其他用户,需要保证当前用户具备创建目录的权限
- 3. 当目录创建好之后系统自动将 /etc/skel 目录中的三个隐藏文件复制到用户的宿主目录中
- 4. 前提条件是新用户具备在自己家目录有写权限
- 2)有两种情况无法将 /etc/skel 中的文件复制到家目录下
- 1. 管理员手动创建普通用户的家目录,而不是创建用户时自动创建的家目录
- a. 家目录的所有者权限是管理员,导致新用户无法在自己家目录下具有写权限
- 2. 没有上级目录无法创建出家目录
- a. 无法将文件复制到本地
用户账号
- 超级用户:root用户,真实环境下很少使用root用户直接操作
- 普通用户:使用最多的用户,可以使用 useradd 创建,分配对应权限
- 程序用户:一般只用于维护某个程序的用户,无法作为登陆系统中进行操作
UID(User IDentity)用户标识号
- root用户的 UID 为 0
- 普通用户的 UID 永远从 1000 开始,创建账户时默认是最大的UID+1
- 程序用户的 UID 在 1000 以内
- id 命令可以查看
用户对应的配置文件
- /etc/passwd 文件是Linux系统中存储用户账号信息的文件。针对所有用户具有可读权限,仅对管理员有可写权限
- /etc/shadow 文件是Linux系统中存储用户密码信息的文件。仅对管理员有可读权限
组对应的配置文件
- /etc/group:存储组帐号基本信息
用户账户管理
- useradd [选项] 用户名 #创建用户
- -u:指定 UID 标识号
- -d:指定宿主目录,缺省为 /home/用户名
- -e:指定帐号失效时间
- -g:指定用户的基本组名,缺省为同名用户
- -G:指定用户的附加组名(或GID号)
- -M:不为用户建立并初始化宿主目录(一般用于程序用户)
- -s:指定用户的登录Shell (bin/bash:表示可以登录,sbin/nologin:表示无法登录通常用于程序用户)
- passwd [选项] 用户名 #修改密码
- -d:清空密码 delete
- -l:锁定密码 lock
- -u:解锁密码 unlock
- -S:查看锁定状态 status
- -s:从「标准输入流」中读取用户的新密码 一般配合 echo "密码" | passwd -s (也就是不需要交互输入密码)
- usermod [选项] 用户名 #修改用户
- -l:更改用户帐号的登录名称
- -L:锁定用户账户
- -U:解锁用户账户
- -s:修改shell环境
- -a:追加附属组,不覆盖原有组
- -G:指定附属组
- userdel [-r] 用户名 #删除用户
- 添加 -r 选项时,表示连用户的宿主目录一并删除
组账号管理
- groupadd [-g GID] 组账号名 #创建组
- gpasswd 组名 #设置组帐号密码(极少用)、添加/删除组成员
- -a:向组内添加一个用户
- -d:从组内删除一个用户成员
- -M:定义组成员列表,以逗号分隔,会替换掉当前组中用户
查询信息
- id #查询用户身份标识
- groups #查询用户所属的组
- users、w、who #查询已登录到主机的用户信息
ls -l 命令表示长格式显示命令可以简写为 ll
- 1、第一列表示文件类型以及权限标识
- 1)第一个字符表示文件类型
- 1. - :普通文件
- 2. l :链接文件
- 3. d :目录
- 2)后面 9 个字符均表示权限,分为三组,每组三个字符
- 1. 第一组:表示属主的权限(所属用户)
- 2. 第二组:表示属组的权限(所属组)
- 3. 第三组:表示其他用户的权限
- 3)每组字符分别使用三个字母表示权限,并且每个权限可以使用数字代替
- 1. r = 读取 = 4
- 2. w = 写入 = 2
- 3. x = 执行 = 1
修改权限
- chmod {[数字|augo +-=rwx]} 文件或目录 #修改文件或目录权限
- u = 属主user g = 属组group
- o = 其他用户other a = 所有用户all
- chown 属主 文件或目录 #修改文件或目录的属组、属主
- chown :属组 文件或目录
- chown 属主:属组 文件或目录
- 其中在修改时添加-R表示递归修改。递归就是父目录有的子目录也有
- umask 022 设置新建目录的默认权限为 755,新建普通文件的默认权限为 644
磁盘和文件系统管理
查看命令
查看命令
- df #查看挂载信息
- -T #显示类型
- -h #显示单位
- -i #查看inode 使用情况
inode 作用
- 存储文件元数据
- 记录文件的大小、权限、所有者、时间、磁盘块位置,不存文件名
- 唯一标识文件
- 系统靠 inode 号区分文件,同一个文件可以多个文件名(硬链接),但 inode 相同
- 定位磁盘数据
- 保存文件真实数据所在的磁盘块指针,操作系统通过 inode 找到文件内容
- 限制文件数量
- 分区 inode 总数固定,inode 耗尽,磁盘空间再大也无法新建文件
top信息
- 第一行:系统整体状态:top - 15:17:09 up 31 days, 56 min, 1 user, load average: 0.11, 0.07, 0.06
- 15:17:09:当前系统时间
- up 31 days, 56 min:系统已经连续运行了 31 天 56 分钟(没有重启过)
- 1 user:当前登录的用户数量(只有 1 个)
- load average: 0.11, 0.07, 0.06:系统负载(分别是 1 分钟、5 分钟、15 分钟的平均负载)
- 负载值≈等待 CPU 处理的任务数
- 对于多核 CPU,负载≤CPU 核心数 ×0.7 一般都算健康,这里明显非常低
- 第二行:进程状态:Tasks: 123 total, 1 running, 122 sleeping, 0 stopped, 0 zombie
- 123 total:系统总共有 123 个进程
- 1 running:正在 CPU 上运行的进程数(这里就是 top 命令本身)
- 122 sleeping:处于休眠 / 等待状态的进程(比如后台服务、等待 IO 的进程)
- 0 stopped:被暂停的进程(比如按 Ctrl+Z 挂起的任务)
- 0 zombie:僵尸进程数量(进程已退出但父进程没回收资源,这里是 0,状态健康)
- 第三行:CPU 使用情况:%Cpu(s): 0.7 us, 0.2 sy, 0.0 ni, 99.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
- us:用户态 CPU 占用(用户进程的计算开销,这里 0.7%,极低)
- sy:内核态 CPU 占用(系统调用、内核操作开销,这里 0.2%)
- ni:nice 值调整过优先级的进程占用(0%,没有这类进程)
- id:CPU 空闲率(99.2%,几乎完全没压力)
- wa:IO 等待(进程等待磁盘 / 网络 IO 完成的时间,0%,说明磁盘完全不忙)
- hi:硬中断处理占用(0%)
- si:软中断处理占用(0%)
- st:虚拟机被宿主机偷走的 CPU 时间(0%,如果是物理机这个值本来就是 0)
- 第四行:物理内存使用:KiB Mem : 1798504 total, 80948 free, 715536 used, 1002020 buff/cache
- 单位是 KiB(千字节,1MiB=1024KiB),换算后约:
- total:总内存 ≈ 1.8GB
- free:完全空闲的内存 ≈ 80MB
- used:已被进程直接使用的内存 ≈ 700MB
- buff/cache:被系统用作缓存 / 缓冲的内存 ≈ 1GB(这部分内存可以被回收给进程使用)
- 第五行:Swap 内存使用:KiB Swap: 0 total, 0 free, 0 used. 895184 avail Mem
- total/free/used 都是 0:说明这台机器没有开启 Swap 交换分区
- avail Mem:系统可用内存 ≈ 895MB(包含 free + 可回收的 cache 内存,比 free 更能反映真实可用量)
- 进程列表区:PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
- 列名 含义
- PID 进程 ID,系统中进程的唯一数字标识
- USER 运行该进程的用户(这里大部分是 root,还有 472、nfsnobody 这类系统用户)
- PR 进程优先级(内核调度用,值越小优先级越高,默认 20)
- NI 进程的 nice 值(-20~19,值越小优先级越高,这里都是 0,默认优先级)
- VIRT 虚拟内存大小(进程申请的总内存,包括物理内存 + swap + 共享库,不是实际占用)
- RES 常驻内存大小(进程实际占用的物理内存,不含 swap 和共享部分)
- SHR 共享内存大小(和其他进程共享的内存部分)
- S 进程状态:S= 休眠,R= 运行,Z= 僵尸,T= 停止
- %CPU 进程占用的 CPU 百分比(这里最高的是 1.0%,阿里云盾进程)
- %MEM 进程占用的物理内存百分比(最高的是 grafana,6.8%)
- TIME+ 进程累计占用的 CPU 时间(比如 499:30.89,就是累计运行了约 500 分钟)
- COMMAND 进程的命令 / 程序名
磁盘管理命令
- fdisk -l [磁盘文件] #查看磁盘分区情况
- fdisk [磁盘文件] #进入磁盘交互界面管理磁盘分区
- n:新建分区
- p 新建主分区(linux中的MBR磁盘系统默认仅有 4 个主分区,扩展分区占用 1 个主分区)
- e 新建扩展分区(分区号范围是1~4)(新建完成扩展分区后才可以建立逻辑分区,因为逻辑分区是依赖于扩展分区)
- l 新建逻辑分区(没有数量限制,容量最大不可以超过扩展分区的容量)
- m 查看帮助
- p 查看分区信息
- d 删除分区
- t 变更分区类型 (83 → Linux 普通分区,82 → Linux swap 交换分区,8e → Linux LVM 物理分区)
- w 保存配置并且退出
- q 不保存退出
格式化系统分区
- mkfs.xfs 参数 #格式化 mkfs.xfs /dev/sdb1 #将sdb1分区格式化为xfs文件类型
- mkfs -t xfs 参数 #格式化
- mkfs -c 参数 #检查、修改分区坏块
挂载磁盘
- 临时挂载
- mount 参数 挂载目标目录 例:mount /dev/sdb1 /ftp/data #将sdb1文件系统挂载到/ftp/data目录
- mount -o usrquota,grpquota 参数 挂载目标目录 #指定挂载类型
- 永久性挂载
- 不会立即挂载完成,需要重启系统或者使用 mount -a 命令刷新文件信息才会被挂载
- 修改 /etc/fstab 文件添加挂载点
- 例:/dev/sdb1 /data/aaa xfs defaults 0 0
- 例:/dev/cdrom /media iso9660 defaults 0 0
创建交换文件系统
- mkswap 参数 例:mkswap /dev/sdb5 #将sdb5分区格式化创建成swap分区
- swapon 参数 #开启swap分区
- swapoff 参数 #关闭swap分区
取消分区挂载
- umount -a #取消所有挂载项
- umount 参数 取消挂载项
磁盘和文件系统管理
LVM:logical volume manager 逻辑卷管理器
LVM:logical volume manager 逻辑卷管理器
- 可以动态调整磁盘容量,提高了磁盘的使用灵活性
- 将多个物理磁盘制作成一个逻辑分区,增加存储容量,加快读写速度
LVM机制的基本概念以及相关命令
- 物理卷:LVM中底层提供容量的磁盘
- pvcreate 文件系统 文件系统 文件系统
- 卷组:使用多个物理卷创建一个卷组,空间是多个物理卷的总和
- vgcreate 卷组名称 物理卷文件系统 物理卷文件系统 物理卷文件系统
- 逻辑卷:使用卷组中的空间创建逻辑卷,最终将逻辑卷挂载到系统中使用
- lvcreate -L 逻辑卷空间 -n 逻辑卷名称 卷组名称
- 查看命令
- pv | vg | lv scan [文件系统] 查看物理卷、卷组、逻辑卷的简要信息 pvscan
- pv | vg | lv display [文件系统] 查看物理卷、卷组、逻辑卷的详细信息 pvdisplay
- 删除命令
- pv | vg | lv remove 删除物理卷、卷组、逻辑卷 pvremove
- 扩展
- 扩展卷组 vgextend 卷组名称 物理卷文件系统 物理卷文件系统 物理卷文件系统ls
- 扩展逻辑卷 lvextend -L +容量 逻辑卷文件系统
- xfs_growfs 刷新文件分区空间
磁盘配额
- 磁盘配额是Linux系统中一项用于限制用户或组对磁盘空间使用的功能。它的主要目标是防止某个用户的过度使用导致整个文件系统的磁盘空间耗尽。
- 实现条件
- 需要Linux内核的支持,并且安装xfsprogs与quota软件包
- 需要在挂载的文件系统上开启用户、组配额功能
开启配额功能
- 临时挂载时使用 mount -o usrquota,grpquota 文件系统 挂载点 usrquota 用户配额 grpquota 组配额
- 永久性挂载需要进入/dev/fstab在defaults字段后添加defaults,usrquota,grpquota 重启系统或者重新挂载生效
设置磁盘配额
- 方式一
- xfs_quota -x -c 'limit -u bsoft=80M bhard=100M isoft=40 ihard=50 zhangsan' /ftp
- -x:表示启动专家模式,在当前模式下允许对配额系统进行修改的所有管理命令可用。
- -c:表示直接调用管理命令。
- -u:指定用户账号对象。
- -g:指定组账号对象。
- bsoft: 设置磁盘容量的软限制数值(默认单位为KB)
- bhard: 设置磁盘容量的硬限制数值(默认单位为KB)
- isoft:
- ihard:
- /ftp/:挂载点目录
- xfs_quota -c 'quota -b -uv zhangsan' /ftp/ 查看zhangsan容量限制
- xfs_quota -c 'quota -i -uv zhangsan' /ftp/ 查看zhangsan文件数量限制
- xfs_quota -x -c 'report -abih' 查看配额信息
- a 查看所有
- b 容量
- i 文件
- h 以人性化显示单位
- xfs_quota -x -c 'off -u' /ftp/ 停止用户配额,-g 表示停止组配额
- 方式二
- edquota -u 用户 #指定lisi用户进行配额
- quotaon -u 参数 #启用目录的用户配额 参数为挂载点
- repquota -u 参数 #查看用户配额情况 参数为挂载点
进程和计划任务管理
进程和线程
进程和线程
- 进程:操作系统资源分配的最小单位,独立内存、独立资源。
- 线程:进程内的执行分支,是 CPU 调度的最小单位,共享进程资源
- 核心区别
- 资源:进程独有内存;线程共享所在进程内存。
- 开销:创建销毁进程开销大;线程轻量、开销小。
- 隔离:进程完全独立,一个崩不影响其他;一个线程挂掉容易导致整个进程崩溃。
- 通信:进程间通信复杂;线程间共享变量即可通信,简单高效。
1、进程相关
- 1)top:动态查看进程,也可以查看系统平均负载
- 1. P:对CPU使用率降序查看(大写)
- 2. M:对内存使用率降序查看
- 2)ps:静态查看进程
- -a:显示所有用户的进程,不显示无终端的进程(不显示守护进程)
- -u:显示详细用户信息,展示:用户名、CPU、内存、启动时间等
- -x:显示无终端的进程(守护进程,如 nginx、mysql),常和 -a 一起用:-ax = 显示所有进程
- -e:显示所有进程(等同于 -A),生产最常用:-ef
- -f:完整格式显示,展示:UID、PID、PPID(父进程)、C、STIME、CMD 等,能看到父子进程关系(查僵尸进程必用)
- 3)pgrep:查询进程PID,进程id
- -l:显示进程名称
- -u:指定用户
- 4)pstree:树形结构查看系统所有进程
- -p:显示 pid
- -u:每个进程显示用户
- -a:列出进程的完整信息
2、进程启动方式
- 1)前台进程:直接终端输入后执行
- 2)后台进程:放到后台运行,不会占用现有终端
- 1. 终端输入指令后,在指令结尾处添加 “&” ,表示将进程放到后台执行,适合临时后台运行,关闭终端会停止
- 不中断:nohup + &,适合需要长期运行(如脚本、服务、下载),关闭终端也不会停止
- 2. 可以通过 jobs 命令查看后台进程的 id 号以及命令
- 3. 输入 fg [id] 将后台进程调到前台执行
- 4. 前台正在执行的进程按 Ctrl + z 组合键放到后台暂停运行
3、关闭进程(下列三个命令都可以使用 -9 选项,强制关闭进程)
- 1)kill:针对 pid 关闭进程,需要知道进程的pid号,一次关闭一个进程
- 2)killall:针对进程名称关闭,直接关闭这个进程,慎用
- 3)pkill:按照条件关闭进程
- -t:针对终端
- -U:针对用户
4、计划任务(通过 date 命令查看系统时间)
- 1)一次性计划任务,使用 at 命令设置,需要启动 atd 进程保证运行
- systemctl start atd
- 1. at [hh:mm] [yyyy-mm-dd] #如果不写年月日则默认最近的时间执行
- #小时:分钟 年-月-日
- at> ps -aux > /data/ps_12_11.txt #计划任务的命令
- at> {ctrl + D} #提交当前命令
- 2. atq:查询未执行的任务
- 3. atrm id:删除未执行的任务
- 2)周期性计划任务:使用 crontab 命令设置,需要启动 crond 进程保证运行
- systemctl start crond
- 1. crontab 进行计划任务的设置
- -e 编辑计划任务
- -u 指定用户
- -l 查看任务列表
- -r 删除任务
- 2. 通过命令输入完后会进入到文档编辑页面,手写计划任务
- 第一个范围表示时间
- 第一个区间:分钟
- 第二个区间:小时
- 第三个区间:日期
- 第四个区间:月份
- 第五个区间:星期
- 格式:时间 需要执行的命令 * * * * * 表示每分钟 /表示每,例:/2 * * * * 表示每两分钟
- 3.进入配置文件修改
- vim /etc/crontab
- 格式:时间 用户 需要执行的命令
死锁
- 什么是死锁:多个进程互相占用对方需要的资源,又都不释放自己已占有的资源,导致互相等待、一直僵持无法执行,就是死锁
- 死锁四个必要条件(缺一不可)
- 互斥条件:资源同一时间只能被一个进程占用;
- 请求与保持:进程已持有资源,还在申请新资源,不释放已有资源;
- 不可剥夺:资源只能自己主动释放,不能被其他进程强行抢走;
- 环路等待:多个进程形成循环等待资源的闭环。
系统故障分析和排查
日志保存位置:默认存放于 /var/log目录中的messages(/var/log/messages) 收集日志的程序叫做:rsyslog
日志保存位置:默认存放于 /var/log目录中的messages(/var/log/messages) 收集日志的程序叫做:rsyslog
分析工具
分析工具
- users:查看登录到系统的用户
- who:查看登录用户的终端、时间
- w:查看登录用户的详细信息
- last:查询成功登录到系统的用户记录和日志
- lastb:登录失败的用户记录、程序日志分析(查询失败登录到系统的用户记录)
- id:显示当前用户或指定用户的 UID、GID 以及所属的用户组信息
常见的故障
- MBR扇区:MBR扇区分区中的第一个扇区(512B)存储系统的引导记录,故障则无法通过硬盘启动系统
- 例子:
- 加新的硬盘作为备用盘
- 创建目录作为备份空间,挂载使用
- dd if=源路径 of=目标路径 bs=大小 count=次数 #备份
- dd if=/dev/zero of=/dev/sda bs=大小 count=次数 #模拟破坏MBR扇区
- 进入急救模式:Troubleshooting Rescue a CentOS system Continue
- 新建目录挂载备份盘,防止找不到数据
- dd if=源路径 of=/dev/sda bs=大小 count=次数 #将备份的MBR 512B的数据写入到/dev/sda中
- GRUB:GRUB是系统中最重要的系统引导程序,用于引导系统的开启,如果GRUB文件损坏则无法正常进入系统,
默认引导文件/boot/grub2/grub.cfg
- 例子:
- 将grub.cfg文件删除或者重命名,使系统无法查询此文件 #模拟文件损坏
- 修改BIOS启动项为光驱启动(+号调整位置,修改完后改回来),进入急救模式(因为MBR没有损坏,会固定进入硬盘)
- chroot /mnt/sysimage/ #配置镜像文件
- grub2-install /dev/sda #安装grub2
- grub2-mkconfig -o /boot/grub2/grub.cfg #恢复grub.cfg文件
- 遗忘root密码
- 例子:
- 开机界面按 e 进入编辑模式
- 在相应位置输入:rw single init=/bin/bash #设置为 rw 权限使用bash环境
- 按Ctrl + x 组合键提交,进入单用户模式
- passwd root #使用 passwd 命令设置密码
- touch /.autorelabel #创建文件,防止因为selinux,无法通过的可能
- exec /sbin/init #重启系统
- 磁盘资源耗尽故障:磁盘空间被大量无用数据占满,空间耗尽。或磁盘存在未使用空间,但是文件数 i 节点耗尽。都会导致无法写入数据
- 例子:
- vim aa.sh (aa为名字随意,.sh为固定文件后缀名) #修改.sh文件,编写脚本
- #!/bin/bash(不写也可能可以,标准写)
- i=1
- while [ $i -le 25999 ](-le代表>=)
- do
- touch /data/file$i
- let i++
- done
- source aa.sh #运行脚本
- df -Th
- df -i #查看文件数
Linux基础网络设置及DHCP服务
- 永久设置:需要进入到配置文件中进行设置/etc/sysconfig/network-scripts/ifcfg-ens33
- 永久设置后必须重启 network 服务才可以刷新使用
- TYPE=Ethernet #指定网卡的类型,常见的类型包括Ethernet(以太网)和Wireless(无线网卡)
- BOOTPROTO=dhcp #指定引导协议,可以是静态(static)或动态(dhcp)
- NAME=ens33 #网卡显示的名称
- DEVICE=ens33 #指定网卡的名称
- ONBOOT=yes #指定网卡是否在系统启动时自动启用
- IPADDR=192.168.1.1 #指定网卡的IP地址
- NETMASK=255.255.255.0 #指定子网掩码
- PREFIX=24 #指定子网掩码,与NETMASK二选一
- GATEWAY=192.168.1.254 #指定默认网关
- DNS1=202.106.0.20 #主DNS地址
- DNS2=222.222.222.222#辅助DNS地址接不同网络之间的通信
管理网卡
- 终端界面输入systemctl restart | stop | start | reload | status network来管理网卡
- ifconfig ens33 up | down 管理网卡#直接拒绝连接网卡
- ifup ens33 | ifdown ens33 #不加载网卡中的IP地址
主机名修改
- hostname #查看当前主机名
- hostname 主机名称 #临时修改主机名称(修改完成后会立即生效,但是需要输入 bash 刷新环境才可以在终端显示)
- vim /etc/hostname #永久性修改主机名称 (重启生效)
hosts文件
- 存储域名和IP地址的映射记录,当本机通过域名、 主机名访问网络资源时,默认优先检查hosts文件
- 仅对当前主机有效,减少了DNS查询过程,加快访问速度
netstat(和ss一样):查看网络连接状态、路由表、接口统计信息等
- -a:显示所有活动连接
- -n:以数字形式显示
- -p:显示进程信息
- -t:查看 TCP 协议相关信息
- -u:查看 UDP 协议相关信息
- -r:显示路由表信息
DHCP结构
- 全局设置:作用整个DHCP服务器,优先级最小
- subnet网段声明(子网区域):作用于当前子网(subnet 网段 netmask 掩码 { })
- host主机声明(主机区域):仅作用当前主机
- 当条目冲突时,会按主机>子网>全局的顺序执行
DHCP相关选项
- default-lease-time 21600; #默认地址租约
- max-lease-time 43200; #最大地址租约
- option domain-name-servers 202.106.0.20,8.8.8.8; #分发的DNS地址
- range 192.168.1.1 192.168.1.10; #设置IP地址池
- option subnet-mask 255.255.255.0; #分发的子网掩码
- option routers 192.168.1.254; #分发的默认网关
- host 名字 { #定义主机声明的区域
- hardware ethernet 00:00:00:00:00:00;#hosts区域中定义客户机的MAC地址
- fixed-address 192.168.1.251; #hosts区域中定义主机的IP地址 }
- dhcp主配置文件在/etc/dhcp/dhcpd.conf ,可以通过修改这个文件配置dhcp服务
FTP文件传输服务
相关概念
相关概念
- 全称File Transfer Protocol,即文件传输协议,是一种应用层的文件传输协议,运行在TCP连接上。
FTP连接模式
- 控制连接:通过 TCP 21 端口进行连接建立
- 数据连接:通过 TCP 20 端口完成数据的上传下载
FTP用户类型
- 匿名用户登录
- 当输入账号时输入 anonymous 或 ftp 用户
- 密码为空
- 一般匿名仅有读的权限
- 本地用户
- 本地系统用户,账号存储在 passwd 和 shadow 文件中
- 生产环境下几乎很少使用本地用户直接访问 ftp 服务,因为安全性比较低
- 默认登录到当前用户的宿主目录内
- 虚拟用户
- 映射一个本地系统用户的权限
- 使用独立的账号、密码文件
- 虚拟用户是虚假的用户,需要本地系统用户提供支持
- 每个虚拟用户可以有不同的权限以及属性
配置vsftp
- 主配置文件:/etc/vsftpd/vsftpd.conf
- 用户控制文件
- /etc/vsftpd/ftpusers #黑名单
- /etc/vsftpd/user_list #通过选项控制黑或者白名单
- 全局配置项
- write_enable=YES:是否启用写入权限
- download_enable=YES:是否允许下载文件
- max_clients=0:限制并发客户端连接数
- max_per_ip=0:限制同一 IP 地址的并发连接数
- 匿名配置项
- anonymous_enable=YES:启用匿名访问(默认是开启的)
- anon_umask=022:匿名用户所上传文件的权限掩码
- anon_root=/var/ftp:匿名用户的 FTP 根目录
- anon_upload_enable=YES:允许上传文件
- anon_mkdir_write_enable=YES:允许创建目录
- anon_other_write_enable=YES:开放其他写入权(重命名、移动、)
- anon_max_rate=0:限制最大传输速率(字节/秒)
- 本地用户配置项
- local_enable=YES:是否启用本地系统用户
- local_umask=022:本地用户所上传文件的权限掩码
- local_root=/var/ftp:设置本地用户的 FTP 根目录
- chroot_local_user=YES:是否将用户禁锢在主目录
- local_max_rate=0:限制最大传输速率(字节/秒)
FTP 虚拟用户
- 1、创建并且生成虚拟用户文件
- 1)手动创建明文文件(建议将文件创建到ftp安装目录下,即:/etc/vsftpd/)
- 1. 奇数行表示用户名
- 2. 偶数行表示密码
- 3. 创建明文文件
- vim /etc/vsftpd/vu.list
- aaa
- 123.aaa
- bbb
- 123.bbb
- ccc
- 123.ccc
- 2)使用 db_load 命令将命令文件转为密文数据库文件
- db_load -T -t hash -f { 明文文件 } { 密文文件 }
- -T = 将明文转为数据库密文
- -t = 指定加密算法,建议使用 hash 算法
- -f = 指定明文文件位置(比如:明文文件名称为vu.list)
- db_load -T -t hash -f /etc/vsftpd/vu.list /etc/vsftpd/vu.db
- 2、创建系统用户,让虚拟用户映射到这个系统用户上,使用系统用户的身份访问 ftp 服务器,建议此用户不登录到系统
- useradd -d /data/ftp -s /sbin/nologin -M virtual (-M的前提是已经有了/data/ftp目录,-M表示不创建宿主目录)
- 3、修改ftp的pam认证文件,让其支持虚拟用户认证,并且指定虚拟用户的数据库文件
- vim /etc/pam.d/vsftpd 在文件中将内部的所有内容全部注释不使用,然后手动添加两行内容
- account required pam_userdb.so db=/etc/vsftpd/vu
- auth required pam_userdb.so db=/etc/vsftpd/vu
- 4、进入ftp主配置文件中,添加选项使其支持虚拟用户登录
- vim /etc/vsftpd/vsftpd.conf
- guest_enable=yes #启用虚拟用户功能
- guest_username=virtual #指定虚拟用户映射的系统用户名称
- allow_writeable_chroot=yes #让虚拟用户具备写入权限
- user_config_dir=/etc/vsftpd/dir #指定存放虚拟用户配置文件的目录
- 5、创建dir目录,在dir目录中创建虚拟用户权限配置文件,并在其中设置权限
- vim /etc/vsftpd/dir
- vim 虚拟用户名(权限配置文件需要和虚拟用户名一样)
- local_root=/var/ftp #设置虚拟用户的 FTP 根目录
- anon_upload_enable=YES #允许上传文件
- anon_mkdir_write_enable=YES #允许创建目录
- anon_other_write_enable=YES #开放其他写入权(重命名、移动、删除)
- /etc/vsftpd/vsftpd.conf的权限命令和/etc/vsftpd/dir的权限配置文件中的权限命令是累加关系
- 例:/etc/vsftpd/vsftpd.conf
- anon_upload_enable=yes
- /etc/vsfptd/dir
- vim web
- anon_other_write_enable=yes
- 则web这个虚拟用户同时拥有上传和其他权限
- 当vim web
- anon_upload_enable=no
- 则web这个虚拟用户仅拥有其他权限,没有上传权限
- 6、使用用户开始验证结果
命令控制中心部分命令
- ? #查询命令
- put #上传文件
- get #下载文件
- delete #删除文件
- rename #重命名
- mkdir #创建目录
DNS服务
DNS运行在UDP协议上,使用53端口
DNS运行在UDP协议上,使用53端口
DNS服务的作用以及类型
DNS服务的作用以及类型
- 域名缓存服务器(cache)
- 通过向其他DNS服务器查询获得到的域名+ip的记录进行存储
- 当客户端通过自己解析时可以直接解析,而不需要再次通过互联网服务器解析
- 减少重复查询的步骤,加快查询速度
- 主要域名服务器(master)
- DNS区域的权威服务器
- 维护整个区域的域名系统
- 从域名服务器(slave)
- 也称为辅助服务器
- 区域文件从主要服务器中获得
- 本身不具备修改权限解析,工作与主要域名服务器基本一样
主要文件
- /etc/named.conf #DNS系统的主要配置文件
- /var/named/ #DNS系统区域文件存储点(用于存储域名配置文件)
主配置文件
- options表示全局配置(转发器在options里面添加 forwarders { 地址 };)
- zone表示区域配置,定义新的区域需要手动添加zone
- type 表示类型,当前实验中:master表示主要服务器,slave表示从服务器
- file指定区域文件名称
- 例子: zone "qm.com" IN { #新建qm.com区域
- type master ; #指定主分区
- file "qm.com" ; #指定文件
- allow-transfer { IP地址 ;}; #指定从域名服务器
- masters { IP地址 ;}; #指定主要域名服务器
- };
- 反向指针:zone "反向IP地址.in-addr.arpa" IN { #定义反向指针区域
- type master;
- file "192.com";
- };
- ps:作为从域名服务器是 file的地址一般是slave/文件
域名配置文件
- 通常存放在/var/named
- IN SOA 域名. www.域名. (
- 0 ;serial
- 1D ;refresh
- 1H ;retry
- 1W ;expire
- 3H) ;minimum
- NS ns.域名.
- ns A IP地址
- www A IP地址
- IP地址 PTR 域名
- file CNAME 域名
- * A 域名
- SOA:表示权威服务器,在一个区域中只有一个权威服务器
- ns :表示名称服务器,每个区域至少有一个名称服务器,具体完成域名解析工作
- A :记录为最常用的域名到IP的正向解析
- MX :记录邮件记录
- PTR :反向指针(反向解析),IP到域名
- CNAME:表示将域名重命名,可以通过file.域名 访问原来的域名
- * :表示所有主机头,任何的主机头.域名都会转换出同一个IP地址(泛域名解析,任何域名都会解析出固定IP)
融合实验
从零搭建一个服务器
从零搭建一个服务器
1、更改网卡设置,配置yum仓库,源代码安装,挂载光盘
1、更改网卡设置,配置yum仓库,源代码安装,挂载光盘
- ifconfig ens33 {IP地址} [掩码(一般无类地址时使用)] #临时修改IP地址
- vim或vi /etc/sysconfig/network-scripts/ifcfg-ens33 #修改网络配置文件,永久修改
- TYPE=Ethernet #指定网卡的类型,常见的类型包括Ethernet和Wireless(无线网卡)
- BOOTPORTO=static #指定网卡类型可以是dhcp或static
- NAME=ens33 #网卡显示的名称
- DEVICE=ens33 #指定网卡的名称
- ONBOOT=yes #指定网卡是否在系统启动时自动启用
- IPADDR=192.168.1.1 #指定网卡的IP地址
- NETMASK=255.255.255.0 #指定子网掩码
- PREFIX=24 #指定子网掩码,于NETMASK二选一
- GATEWAY=192.168.1.245 #指定默认网关
- DNS1=1.1.1.1 #主DNS地址
- DNS2=2.2.2.2 #辅助DNS地址
配置yum仓库有两种方式
将所有文件删除,任何手写内容
将所有文件删除,任何手写内容
- mount /dev/cdrom /media #挂载 iso 文件,使系统具备 rpm 包
- rm -rf /etc/yum.repos.d/* #删除所有 yum 配置文件
- vim /etc/yum.repos.d/abc.repo #创建 yum 配置文件
- [haha] #yum仓库当前区域名称,名称随意
- name=hhhh #当前区域名称,名称随意
- baseurl=file:///media #指定本地系统 rpm 包存放目录
- gpgcheck=0 #是否检查每个 rpm 包,0表示不检查,1表示检查
- enabled=1 #是否开启 yum 仓库,0表示关闭,1表示开启
仅删除网络yum文件,修改本地yum文件(yum工具优先查看网络yum文件)
- mount /dev/cdrom /media #挂载 iso 文件,使系统具备 rpm 包
- cd /etc/yum.repos.d/ #进入到 yum 配置文件的目录中
- rm CentOS-Base.repo #删除网络 yum 配置文件
- vim CentOS-Media.repo #使用 vi 编辑器进入到本地 yum 配置文件中
- [c7-media] #yum仓库当前区域名称,名称随意
- name=CentOS-$releasever - Media #当前区域名称,名称随意
- baseurl=file:///media #指定本地系统 rpm 包存放目录
- gpgcheck=0 #是否检查每个 rpm 包,0表示不检查,1表示检查
- enabled=1 #是否开启 yum 仓库,0表示关闭,1表示开启
使用yum工具的命令
- yum -y install [ 服务名称 ] #安装服务
- yum -y remove [ 服务名称 ] #卸载服务
源代码编译安装
- yum -y install gcc-c++ pcre* apr* make* #安装必要rpm包
- tar zxvf http.gz -C /usr/src #释放文件到指定区域
- ./configure --prefix=/usr/local/httpd && make && make install #指定路径并安装
- /usr/local/httpd/bin/apachectl start #开启httpd服务
- iptables -F #清空防火墙条目
- setenforce 0 #关闭selinux
挂载光盘
- mount /dev/cdrom /media #临时挂载光盘
- vim /etc/fstab #永久挂载光盘
- /dev/cdrom /media xfs default 0 0
2、配置LVM
- 加入所需光盘
- fdisk /dev/sdb
- n p 回车 回车 回车
- pvcreate /dev/sdb1 /dev/sdc1 /dev/sdd1 #创建物理卷
- vgcreate qm /dev/sdb1 /dev/sdc1 /dev/sdd1 #创建卷组
- lvcreate -L 50G -n web(逻辑卷名称) qm(卷组名称) #创建逻辑卷
- mkfs.xfs /dev/mapper/qm-web #格式化逻辑卷
- vim /etc/fstab
- /dev/mapper/qm-web /usr/local/httpd/htdocs xfs defaults 0 0 #永久挂载逻辑卷
3、ftp
- 在linux服务器中,ftp服务常用的软件为vsftp
- yum -y install vsftpd #安装ftp
- cd /etc/vsftpd
- vim vu.list #编写虚拟用户配置文件 账号密码
- db_load -T -t hash -f vu.list vu.db #明文文件转换密文文件
- chmod 600 vu.db #保证vu.db文件安全
- cp -p vsftpd.conf vsftpd.conf.bak #复制文件作为备份
- grep -v '^#' vsftpd.conf.bak > vsftpd.conf #过滤文件
- vim vsftpd.conf
- guest_enable=yes #允许虚拟用户登录
- guest_username=virtual #映射virtual账户
- allow_writeable_chroot=yes #允许虚拟用户写入
- user_config_dir=/etc/vsftpd/dir #指定虚拟用户配置文件路径
- useradd -d /usr/local/httpd/htdocs -s /sbin/nologin -M virtual #创建用户,指定宿主目录,不允许登录,不创建宿主目录
- vim /etc/pam.d/vsftpd #编辑登录文件
- account required pam_userdb.so db=/etc/vsftpd/vu
- auth required pam_userdb.so db=/etc/vsftpd/vu
- cd /etc/vsftpd/dir
- vim 虚拟用户名 (权限配置文件需要和虚拟用户名一样)
- local_root=/var/ftp #设置虚拟用户的 FTP 根目录
- anon_upload_enable=YES #允许上传文件
- anon_mkdir_write_enable=YES #允许创建目录
- anon_other_write_enable=YES #开放其他写入权(重命名、移动、删除)
4、DNS
- yum -y install bind #安装DNS服务
- vim /etc/named
- zone '域名' IN{ #创建区域
- type master;
- file "文件";
- } ;
- cd /var/named
- cp -p named.empty 文件
- vim 文件
- IN SOA 域名. www.域名. (
- 0 ;serial
- 1D ;refresh
- 1H ;retry
- 1W ;expire
- 3H) ;minimum
- NS ns.域名.
- ns A IP地址
- www A IP地址
- IP地址 PTR 域名
- file CNAME 域名
- * A 域名
5、DHCP
- yum -y install dhcp
- vim /etc/dhcp/dhcpd
- default-lease-time 21600; #默认地址租约
- max-lease-time 43200; #最大地址租约
- option domain-name-servers 202.106.0.20,8.8.8.8; #分发的DNS地址
- range 192.168.1.1 192.168.1.10; #设置IP地址池
- option subnet-mask 255.255.255.0; #分发的子网掩码
- option routers 192.168.1.254; #分发的默认网关
- subnet 网段 netmask 掩码 { #声明子网区域
- }
- host 名字 { #定义主机声明的区域
- hardware ethernet 00:00:00:00:00:00;#hosts区域中定义客户机的MAC地址
- fixed-address 192.168.1.251; #hosts区域中定义主机的IP地址 }
web网站服务
硬连接和软连接
硬连接和软连接
- 硬连接:创建一个复制文件,修改复制文件源文件也会被修改,删除一个文件另一个文件不会受到影响
- 软连接:创建一个快捷方式,快捷方式会通过连接跳转到源文件,删除源文件,快捷方式则无法使用
主配置文件中的全局配置项
- ServerRoot:安装目录
- ServerAdmin:管理员邮箱
- User:运行服务的用户身份
- Group:运行服务的组身份
- ServerName:网站服务器的域名 **
- DocumentRoot:网页文档的根目录,索引文件的路径 **
- Listen:监听的IP地址、端口号 **
- PidFile:保存httpd进程PID号的文件
- DirectoryIndex:指定索引页(首页)名称 **(指定索引文件)
- ErrorLog:错误日志文件的位置
- CustomLog:访问日志文件的位置
- LogLevel:记录日志的级别,默认为warn
- Timeout:网络连接超时,默认为300秒
- KeepAlive:是否保持连接,可选On或Off
- MaxKeepAliveRequests:每次连接最多请求文件数
- KeepAliveTimeout:保持连接状态时的超时时间
- Include:需要包含进来的其他配置文件
编译安装httpd时,常见的配置参数
- ./configure:执行安装配置文件
- --prefix:指定安装路径
- --enable-so:启用动态模块功能,可以在使用中添加需要的模块功能,并且不影响业务的运行
- --enable-rewrite:启用地址重写功能,用于网站的优化和目录迁移
- --enable-charset-lite:启动字符集支持,便于使用各种字符集编码的网页
- --enable-cgi:CGI 是一种在 Web 服务器和客户端之间传递数据的协议,允许服务器执行外部程序并将结果返回给客户端。
- make:将软件编译为二进制文件让系统可以识别
- make install:安装到系统
httpd 服务的主要目录和文件 apache2为例
- 安装目录:/usr/local/apache2/
- 主配置文件:/usr/local/apache2/conf/httpd.conf
- 网页目录:/usr/local/apache2/htdocs/index.html
- 服务脚本:/usr/local/apache2/bin/apachectl
- 执行程序:/usr/local/apache2/bin/httpd
- 访问日志: /usr/local/apache2/logs/access_log
- 错误日志: /usr/local/apache2/logs/error_log
添加httpd系统服务
- ln -s /usr/local/apache2/bin/* /usr/local/bin/ #通过软连接将httpd的命令连接到系统中,使系统可以直接使用
- vim /etc/systemd/system/httpd.service #修改系统服务配置文件,将httpd服务加入系统,由系统管理
- [Unit]
- Description=The Apache HTTP Server
- After=network.target
- [Service]
- Type=forking
- ExecStart=/usr/local/apache2/bin/apachectl start
- ExecStop=/usr/local/apache2/bin/apachectl stop
- ExecReload=/usr/local/apache2/bin/apachectl graceful
- PIDFile=/usr/local/apache2/logs/httpd.pid
- PrivateTmp=true
- [Install]
- WantedBy=multi-user.target
- systemctl daemon-reload #重启systemctl服务
httpd服务的基本配置
- /usr/local/apache2/bin/htpasswd -c /usr/local/apache2/conf/.awspwd zhangsan #创建一个专用于web服务的账号。.表示隐藏
- vim /usr/local/apache2/conf/httpd.conf
- ServerName 域名 #修改域名
- <Directory "/usr/local/awstats/wwwroot">
- Order allow,deny #访问控制的检查顺序
- Allow from all #允许所有IP访问(但会被后续规则覆盖)
- Require all denied ## 拒绝所有IP访问
- Require ip 127.0.0.1 ## 仅允许本机(127.0.0.1=localhost)访问
- Require ip 192.168.160.1 #仅允许 192.168.160.1 这个IP访问
- AuthType Basic #启用基础HTTP认证(账号密码验证)
- AuthName "Restricted Area - Please Login" #登录弹窗的提示文字
- AuthUserFile "/usr/local/apache2/conf/.awspwd" #指定web用户文件路径
- Require valid-user #请求合法用户
虚拟的web主机:优势:在一台物理机中部署多个独立的web站点,相互之间互不干扰
- 基于域名的web主机
- 首先修改windos/system32/device/etc/hosts
- mkdir -p /html/aaa
- echo "this is aaa" > /html/aaa/index.html
- vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
- <VirtualHost *:80>
- DocumentRoot "/html/aaa" #指定网站存储文档的路径
- ServerName www.aaa.com #域名
- ErrorLog "logs/aaa.com-error_log" #错误日志存放位置
- CustomLog "logs/aaa.com-access_log" common #正确日志存放位置
- </VirtualHost>
- vim /usr/local/apache2/conf/httpd.conf
- <Directory />
- AllowOverride none
- # Require all denied
- Require all granted #开启允许访问权限
- </Directory>
- # Virtual hosts
- Include conf/extra/httpd-vhosts.conf #包含虚拟主机的配置文件
- systemctl restart httpd
- 基于IP的web主机(一个IP对应一个web服务)
- 需要添加网卡
- vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
- <VirtualHost 192.168.112.100:80>
- DocumentRoot "/html/aaa"
- ServerName www.aaa.com
- ErrorLog "logs/aaa.com-error_log"
- CustomLog "logs/aaa.com-access_log" common
- </VirtualHost>
- systemctl restart httpd
- 基于端口的web主机
- vim /usr/local/apache2/conf/extra/httpd-vhosts.conf
- <VirtualHost 192.168.112.100:8888>
- DocumentRoot "/html/aaa"
- ServerName www.aaa.com
- ErrorLog "logs/aaa.com-error_log"
- CustomLog "logs/aaa.com-access_log" common
- </VirtualHost>
- vim /usr/local/apache2/conf/httpd.conf
- Listen 80
- Listen 8888
- Listen 6666
- systemctl restart httpd
MySQL(在Linux上)
安装mysql
安装mysql
- yum install -y gcc* make* openssl*
- tar -zxvf mysql-5.7.32-el7-x86_64.tar.gz -C /usr/src/ #解压压缩包
- mv /usr/src/mysql-5.7.32-el7-x86_64/ /usr/local/mysql #移动到/usr/local并重命名为mysql
- mkdir -p /data/mysql #创建一个存储mysql数据文件目录
- useradd -M -s /sbin/nologin -d /usr/local/mysql/ mysql #创建mysql用户用于管理mysql程序
- chown -R mysql:mysql /usr/local/mysql #更改/usr/local/mysql的属主和属组
- chown -R mysql /data/mysql/ #更改/data/mysql的属主和属组
- /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
- #运行mysqld initialize:初始化 指定管理用户,指定基础目录,指定数据目录
- 复制第一次的临时密码
- rm -rf /etc/my.cnf #删除基础配置文件
- cd
- vim my.cof #配置基础文件
- [mysqld]
- datadir=/data/mysql
- socket=/tmp/mysql.sock
- user=mysql
- symbolic-links=0
- mv my.cnf /etc/my.cnf #更改配置文件
- cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql #更改配置文件
- vim /etc/init.d/mysql
- basedir=/usr/local/mysql
- datadir=/data/mysql
- chmod 755 /etc/init.d/mysql
- ln -s /usr/local/mysql/bin/mysql /usr/local/bin/
- chkconfig --add mysql
- chkconfig --level 2345 mysql on
- systemctl start mysql #启动mysql
- mysql -u root -p #登录mysql
数据库基础知识
- 数据库:数据库(Database,简称 DB) 是按照一定数据结构来组织、存储和管理数据的仓库,本质是为了高效地存储和检索大量
关联数据,解决传统文件存储(如 TXT、Excel)的低效、易出错、难共享等问题
- 关系型:MySQL、Oracle、PostgreSQL、SQL Server
- 非关系型:MongoDB(文档型)、Redis(键值型)、Elasticsearch(搜索型)
- 索引:索引是数据库中为加速查询而创建的一种特殊数据结构,用于提升查询速度
- 事务:事务是数据库中一组不可分割的操作集合,这组操作要么全部执行成功,要么全部执行失败
- 视图:视图是基于一个或多个表的查询结果创建的 “虚拟表”,视图本身不存储数据,数据还是存在原始表中,视图只是一个"查询窗口"
- ACID
- A - Atomicity(原子性):事务是一个 “原子” 操作单元,要么全部执行,要么全部不执行。
- 例:转账事务中,扣款和加钱两个操作,要么都完成,要么都不做(如果中间断电,会自动回滚到操作前状态)
- C - Consistency(一致性):事务执行前后,数据库的数据完整性约束不被破坏。
- 例:转账前 A+B 余额 = 2000 元,事务执行后 A+B 余额必须还是 2000 元,不能出现总额增加或减少的情况
- I - Isolation(隔离性):多个事务同时执行时,一个事务的执行不能被其他事务干扰,各事务之间相互隔离
- 例:两个用户同时给一个账户转账,事务 A 和事务 B 不会互相影响,不会出现 “重复扣款” 或 “金额计算错误”
- D - Durability(持久性):一个事务一旦提交成功,它对数据库中数据的修改就是永久性的,接下来的系统故障、断电等都不会影响已提交的数据。
- 例:转账事务提交后,即使服务器立刻断电,重启后 A 的扣款和 B 的加钱结果依然会保留。
- MySQL用户名中的%和localhost的含义:%代表任意主机,localhost代表本机
- mysql默认的端口号是3306
- mysql安装支持的机器类型有开发者机器,服务器机器,专用mysql机器
- MySQL的默认用户是root
- 创建表时要考虑表名,列名,数据类型,主键,外键,非空约束,默认值,自动增长
- 关于主键的说明
- 主键是确定数据库中的表的记录的唯一标识字段
- 一个表只能有一个主键
- 主键列可以是表中的一个字段,也可以包含多个字段
- 主键的值是唯一的且不为空
- 尽量选择更新少的一个字段为主键
- mysql常用的数据类型
- 文本类型: char固定长度字符, varchar可变长度字符, text 长文本
- 日期和时间: datetime:年月日时分秒, date:年月日
- 数: int 整数,float:小数,浮点数,decimal定点数
- 创建数据库:CREATE DATABASE IF NOT EXISTS 数据库名
- 创建表:CREATE TABLE IF NOT EXISTS 表名(核心字段)
- 单行插入:insert into 表名 [(列1,列2,…)] values(值1,值2,…)
- SQL语句不区分大小写
- 如果不写列名,代表给所有列(包括自增列)赋值
- 如果写列名,列和值的数量、类型一致
- 表名,列名直接写,不能加单引号,
- 文本类型和日期类型需要用引号括住,数值类型直接写
- 不能违反任何约束
- 所以符号都是英文的
- 如果要插入默认值,可以写 default(不能加引号),也可以不出列名
- 多行插入:INSERT INTO 表名(列名,...)
- SELECT 列名,...
- FROM 源表名
- Insert into 表名 [(列1,列2,…)]
- values (值1,值2,…),... (值1,值2,…)
- 修改:update 表名 set 列1=值1,列2=值2 [where 更新条件]
- 删除:delete from 表名 [where 删除条件]
- 查看表结构:describe 表名 或desc 表名
- 查看表、库:show tables、show databases
- mysql的运算符
- 算术运算符: + - *(乘法) /(除法) %(取余)
- 赋值运算符:=
- 比较运算符:等于=、大于>、小于<、不等于<>、大于等于>=、小于等于<=
- 逻辑运算符: AND(且) OR(或者) NOT(非)
- SQL语句分类及各类中包含的命令
- DQL 数据查询语言,包含select
- DML 数据操作语言, 包含insert ,update , delete
- DDL 数据定义语言,包含create table 建表,drop table 删表等
- DCL 数据控制语言,包含 grant,revoke等
- drop、delete、truncate的区别
- delete:删表里的数据,表还在,可恢复,慢
- truncate:清空整张表,表还在,不可恢复,快
- drop:删整个表 / 库,表 + 数据全没了,最危险
- 简单查询
- SELECT 列名,...
- FROM 表名
- [WHERE 查询条件表达式]
- [ORDER BY 排序的列名[ASC或DESC]] -- asc是升序,是默认值,desc是降序
- [limit 行数] -- 限制结果的行数
- 查询学生表中邮箱为空和不为空的写法
- select * from 学生表 where 邮箱 is null
- select * from 学生表 where 邮箱 is not null
- 起别名的写法:select 列名 [as] 别名 from 表名
- 数字函数
- rand 返回0到1之间的随机数
- ceil 向上取整
- floor 向下取整
- round 四舍五入
- 字符函数
- substring 字符串截取
- trim 去掉两边空格
- concat 字符串拼接
- length 返回字符串的字节长度
- instr 返回字符串中子子符串第一个出现的位置
- right 从字符串右侧返回制定数目字符串
- left 从字符串左侧返回制定数目字符串
- replace 替换字符串
- 日期函数
- now() 获得当前时间
- curdate 获得当前日期
- curtime() 获得当前时间
- date_add 日期+后面给的时间
- date_sub 前面时间减后面时间
- datediff 间隔天数
- 模糊查询
- like :where 列名 like ‘值通配符’
- 通配符:%代表任意长度字符,_代表一个字符
- between..and: where 列名 between 小的值 and 大的值
- in: where 列名 in (值1,值…)
- SQL中连接接查询的都有那些?并写出具体的语法格式
- 内联接语法一:
- select 列名 from 表1
- inner join 表2 on 表1.列名=表2.列名
- 内联接语法二:
- select 列名 from 表1,表2 where 表1.列名=表2.列名
- 左外联接语法:
- select 列名 from 左表
- left join 右表 on 表1.列名=表2.列名
- 右外联接:
- 用右表匹配左表的数据,主要显示右表的数据,
- 不管是否匹配上,右表的数据都显示
- 聚合函数
- SUM()求和
- AVG()平均分
- MAX()最大值
- MIN()最小值
- COUNT(*或者列名)计数
- SELECT 聚合函数(列名) FROM 表名 [WHERE 条件]
- 查询语句的语法
- SELECT DISTINCT 列名1 别名,列名2 as 别名…
- FROM 表1
- [inner|left|right] join 表2 on 表1.列名=表2.列名
- [WHERE 条件表达式] #查询条件
- [GROUP BY 列名] #分组,多列分组逗号隔开
- [HAVING 条件表达式] #对分组后的结果进行筛选
- [ORDER BY 列名 [ASC|DESC]] #排序,asc 升序(默认值),desc 降序,多列排序逗号隔开
- [LIMIT [开始行号,]条数]; #限制行数
- 权限赋予
- GRANT(grant) [权限1, 权限2, ... | ALL PRIVILEGES(all privileges)(所有权限)]
- ON(on) [数据库名.表名 | *.* | 数据库名.*]
- TO(to) '用户名'@'访问主机'
- 权限1, 权限2:具体权限,如 select(查询)、insert(插入)、update(更新)、delete(删除)、create(创建)、drop(删除库 / 表)等
- *.* 所有数据库的所有表(全局权限)
- FLUSH PRIVILEGES; #刷新权限
- show grants for 'root'@'%'; #查看所有登录root用户的权限
- REVOKE(revoke) ALL PRIVILEGES ON test_db.* FROM 'test_user'@'%'; #撤销 test_user 对 test_db 数据库的所有权限
- select host,user from user; #查看用户登录管理,看哪个用户可以登录到哪个主机
- 全量备份
- 在linux命令行中输入
- cd /usr/local/mysql/bin
- mysqldump -u root -p 数据库名> /tmp/数据库名.sql (也可以用于数据库导出)
- 输入密码
- 修改密码
- set password=password('新密码')
- ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'
LAMP平台部署
- LAMP平台:也就是Linux,Apache,Mysql,PHP连接到一起部署一个平台
- yum install -y systemd-devel libxml2-devel sqlite-devel libcurl-devel libpng-devel #安装必要依赖
- yum install -y gcc gcc-c++ make openssl-devel pcre-devel expat-devel bzip2 wget tar
- tar -jxvf php-7.4.16.tar.bz2 -C /usr/src/ #解压
- rpm -ivh oniguruma-6.8.2-1.el7.x86_64.rpm
- rpm -ivh oniguruma-devel-6.8.2-1.el7.x86_64.rpm
- cd /usr/src/php-7.4.16
- ./configure --prefix=/usr/local/php \
- --with-apxs2=/usr/local/apache2/bin/apxs \
- --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
- --enable-mbstring --enable-fpm --enable-zip \
- --with-openssl --with-zlib
- make && make install #编译安装
- cp php.ini-production /usr/local/php/lib/php.ini
- /usr/local/php/bin/php -v #查看版本,验证php是否安装成功
- vim /usr/local/apache2/conf/httpd.conf
- LoadModule php7_module modules/libphp7.so #插入php模块
- AddType application/x-httpd-php .php #
- DirectoryIndex index.php index.html #指定索引文件,有顺序
- echo "<?php phpinfo();?>" > /usr/local/apache2/htdocs/index.php #验证方式
- systemctl restart httpd
- mysql -uroot -p
- CREATE DATABASE wordpress DEFAULT CHARSET utf8mb4; #创建需要数据库
- cd /usr/local/apache2/htdocs
- tar -zxvf latest-zh_CN.tar.gz -C /usr/local/apache2/htdocs
- cd /usr/local/apache2/htdocs/wordpress
- cp wp-config-sample.php wp-config.php
- vim wp-config.php
- define('DB_NAME', 'wordpress');
- define('DB_USER', 'root');
- define('DB_PASSWORD', 'Root@123');
- define('DB_HOST', '127.0.0.1');
shell脚本
分布式拒绝服务攻击的英文简称为 DDoS(Distributed Denial of Service (Attack))
分布式拒绝服务攻击的英文简称为 DDoS(Distributed Denial of Service (Attack))
shell:直译为壳,是用户与操作系统内核之间的一层接口程序,用户可以通过shell与计算机进行交互。在现代操作系统中,shell仍然是命令行
shell:直译为壳,是用户与操作系统内核之间的一层接口程序,用户可以通过shell与计算机进行交互。在现代操作系统中,shell仍然是命令行
用户和系统沟通的核心工具。本质上是一个命令解释器
用户和系统沟通的核心工具。本质上是一个命令解释器
- 主要功能
- 提供命令行界面让用户执行操作系统的各种命令
- 支持编写shell脚本,通过组合命令实现自动化任务处理
- 允许用户管理和操作环境变量,影响程序执行环境
- 提供便捷的命令别名功能和强大的管道功能,方便数据流的处理和多个命令的协同工作
Shell 脚本
- 可以将需要执行的指令存储到文本中,按照顺序依次执行
- 也可以通过Shell语句将文本中的命令编写为条件类型,满足条件后执行
- 执行脚本的命令
- sh 脚本文件
- source 脚本文件
- ./脚本文件(必须添加执行权限)
- 一个完整的Shell脚本需要具有脚本生明(解释器)、注释信息、可执行语句
变量的组成
- 变量名:使用固定的名称,可以由系统预设也可以用户手动设置
- 变量值:可以根据实际使用情况、系统环境变化而变化,不一定是固定的
变量的类型
- 自定义变量:由用户自行设定,管理、修改和使用
- 当某个程序或者脚本需要重复性使用一个值时,那么就可以使用变量代替
- 这样在需要进行值修改时,仅需要修改变量中的值即可
- 变量定义的规则,变量名 = 变量值:a=10
- 可以赋予任何类型的值,等于号两边不允许出现空格,如果必须添加有空格的值时必须使用双引号
- 赋值时使用引号
- 双引号" ":会把引号的内容当成整体来看待,允许通过$符号引用其他变量值
- 单引号' ':会把引号的内容当成整体来看待,禁止引用其他变量值,shell中特殊符号都被视为普通字符
- 反撇号` `: 反撇号和$( )一样,引号或括号里的命令会优先执行,执行后的结果就是赋予给变量的值,
- 如果存在嵌套,反撇号不能用,推荐使用$( )
- 环境变量:由系统自动设定,用于设定工作环境,Linux常见的环境变量为:$PATH,$LANG,$HOME
- 可以通过env命令查看当前系统下的所有环境变量
- 位置变量:通过命令行给脚本程序传递参数
- 表示方法为$n,其中n一般表示1-9之间的任意数字
- 预定义变量:Bash中内置的一类变量,不可以直接修改
- $#:命令行中位置参数的个数
- $*:所有位置参数的内容
- $?:前一条命令执行后的返回状态,返回值为0表示执行正确,非0均表示执行出现异常(127表示commandnot found(未找到命令))。
- $0:脚本本身的文件名
重定向
- 重定向输入
- <:从指定的文件输入数据
- 重定向错误输出
- 2>:将错误信息保存到指定的文件(覆盖原有内容)
- 2>>:将错误信息追加到指定的文件中
- 重定向混合输出
- &>:将标准输出、标准错误的内容保存到同一个文件中(覆盖原有内容)
- 重定向混合输出
- &>>:将标准输出、标准错误的内容追加到同一个文件中
- 2>&1或者&>正确输出和错误信息同时保存
- &>/dev/null #表示静默输出,也就是看的好看(屏蔽输出)
整数变量的运算
- 格式:expr 变量1 运算符 变量2[运算符 变量3]...
- 格式二:echo $(( 变量 运算符 变量 )) #常用这个
- 常用运算符:
- 加法运算:+
- 减法运算: -
- 乘法运算: \*
- 除法运算: /
- 求模(取余)运算: %
特殊进程状态变量
- exit 数字:脚本/程序的最终退出码
- return 数字:函数的返回状态
- read 从键盘读入变量值:read‐p"提示信息:" 变量名
- unset:可以删除变量
脚本的三种执行方式
- 直接调用解释器:bash script.sh
- 特点:
- 新开一个子 Shell 进程运行脚本
- 当前 Shell 环境变量 不会改变
- 脚本里的 exit 只退出子 Shell,不影响当前 Shell
- 给脚本加执行权限,直接运行(生成环境大部分是这种类型):chmod +x script.sh ./script.sh
- 特点:
- 根据脚本首行的 shebang(#!)(#!/bin/bash 或 #!/bin/sh)来决定用哪个解释器运行
- 如果没写 shebang(#!),就会用当前 Shell(一般是 /bin/bash)执行
- 本质上和 bashscript.sh 一样,也是新开子 Shell
- 使用 source:source script.sh(. script.sh# 等价写法)
- 特点:
- 不会开启子 Shell,在当前 Shell 里执行脚本
- 脚本里的变量、函数、环境修改 会直接影响当前 Shell
- 如果脚本里有 exit,会把当前 Shell 也直接退出掉
Shell 脚本的执行过程
- 先查找系统环境变量ENV,该变量指定了环境文件(加载顺序通常是/etc/profile、~/.bash_profile、~/.bashrc、
/etc/bashrc 等),在加载了上述环境变量文件后,Shell 就开始执行Shell脚本中的内容
部分shell脚本格式
部分shell脚本格式
- #!/bin/bash #引用bin下的bash也就是常用的bash shell
- cat > /usr/local/apache2/conf/httpd.conf << EOF 内容 EOF #将内容以替换的方式写入到httpd.conf文件中
- 在文件的末行模式中输入:set ff(fileformat)=unix 转换字符模式为unix,用于部分windows文本文件上传到Linux后不可用的情况
- mysql -u 用户 -p密码 -e "具体mysql的命令"
- -e : 直接执行 SQL,不用进 MySQL 终端
条件测试操作
- -d#是否为目录 directory
- -e#文件或目录是否存在 exist
- -f #是否为文件 file
- -r#是否具有读取权限 read
- -w #是否具有写入权限 write
- -x #是否具有执行权限 execute
- -eq #等于 equalto
- -ne #不等于 not equalto
- -gt #大于 greater than
- -lt #小于 less than
- -le #小于或等于 lessthanorequalto
- -ge #大于或等于 greaterthanorequalto
- 字符串比较
- [字符串1 = 字符串2 ]
- [字符串1 != 字符串2 ]
- [-z字符串]
- =:字符内容相同
- !=:字符内容不同-
- z:字符内容为空
- 在条件测试中的逻辑运算符
- &&,并且,必须每个命令都成立,使用test时&&可以替换为-a(与)
- ||,#或者,多条件中成立一条即可,使用test时||可以替换为-o(或)
- !,不是(非)
- 在命令中的逻辑运算符
- &&表示前一个命令执行成功才执行下一个命令
- ||表示前一个命令执行失败才执行下一个命令
- if语句
- 结构一
- if [ 条件判断式 ];then 或 if [ 条件判断式 ]
- 命令1 then
- fi 命令
- fi
- 结构二
- if [ 条件判断式 ]
- then 命令1
- else 命令2
- fi
- 结构三
- if[ 条件判断式1 ]
- then
- #如果表达式1为真,则执行这里的语句
- elif[ 条件判断式2 ]
- then
- #如果表达式1为假,但表达式2为真,则执行这里的语句
- else
- #如果所有表达式都为假,则执行这里的语句
- fi
- case语句:case是直接判断对应的条件执行命令块,常用于菜单栏
- case "变量" in
- 值1)
- 指令1...
- ;;
- 值2)
- 指令2...
- ;;
- *)
- 指令3...
- esac
循环:在循环中都可以执行条件判断语句
- for:主要用于执行次数有限的循环
- 结构一
- for 变量名 in 取值列表
- do
- 命令
- done
- 例子:fori in12345
- do
- echo "$(expr $i \* $i )"
- done
- 结构二
- for (( 变量;变量条件;算法(变量累加或减) )) #满足条件则执行do,不满足条件则执行done,变量累加实际在do和done之间
- do
- 命令
- done
- 例子:for((i=1;i<=5;i++))
- do
- echo $i
- done
- while:更适合在特定条件下重复操作,可以使用true和false进行判断,true表示条件永远是成立的,如果没有exit指令,则会
一直循环下去,false表示循环体永远不会被执行
- 结构一
- while [ 条件测试操作 ]
- do
- 命令
- let 变量++ #表示累加,在while中需要加let作为前缀
- done
- break:表示直接结束当前循环,跳出循环
- continue:表示结束本轮循环,继续循环
- 函数:函数名 ( ) {具体的命令}
- 在函数里的变量是局部变量。定义函数后,就可以在shell脚本中引用
- 循环语句和if语句都可以互相套
Linux三剑客
grep 负责找文本,sed 负责改文本,awk 负责分析 / 统计文本
grep 负责找文本,sed 负责改文本,awk 负责分析 / 统计文本
- grep
- 作用:在文件里查找包含指定内容的行
- 只做搜索、过滤
- 输出匹配到的行
- 最简单、最常用
- sed
- 作用:对文本进行替换、删除、插入、修改 **
- 擅长编辑、修改文本
- 最常用:替换字符串
- 流式处理,不修改原文件(加 -i 才会改)
- awk
- 作用:按列处理文本,做分析、统计、计算 **
- 把一行按空格 / 制表符分成列(字段)
- 擅长:取某一列、求和、统计、格式化输出
- 更像一门小语言
uname -r:查看系统内核版本
awk:执行 awk 时,它每次都会从文本中扫描每一行,然后执行大括号{}内的动作
awk:执行 awk 时,它每次都会从文本中扫描每一行,然后执行大括号{}内的动作
- awk 'pattern { action }' file pattern:匹配条件(可选),action:要执行的操作(用 {} 包裹)
- 如果省略 pattern,则对所有行执行 action,如果省略 action,默认打印整行({ print })
- -F :指定描绘一行中数据字段的文件分隔符,默认为空格
awk内置变量
- $0 #当前记录,也就是打印所有,打印整行内容
- $1,$2,$3...$n #当前记录的第n个字段,也就是只打印对应列,需要-F分出列才可以使用或以空格分隔的文件,用于传参
- NF #当前记录的字段数(也就是列数)
- NR #表示行号 NR==1表示第一行 (print NR)表示打印行号
- $NF #表示分割后的最后一列,所以倒数最后第二列可以写成$(NF-1)
- awk -F":" '{print $1}' /etc/passwd #按照:分列,然后打印第一列
- awk -F":" '{print $2,$5}' /etc/passwd #按照:打印第二列 、第五列
- awk -F":" '{print $1,$NF}' /etc/passwd #按照:打印第1列和最后一列数据
- awk 'NR==2 {print $2}' #找第二行,第二列
- awk 'NR>1 {print $1}' #NR>1,跳过表头常用
print和printf
- print:标准化输出,正常输出需要显示的内容
- printf:通过选项添加输出的格式,不会自动换行
- %s:代表字符串 %15s:表示第一列占用 15 个字符,以字符串形式输出
- %d:代表整数 等同于[0-9]
- \n:代表换行符 \n:用于自动换行,由于 printf 不会自动换行,需要换行时在末尾添加
模式匹配
- //:找包含某个特定字符的行,就把字符放进两个斜杠里
- 全行匹配:awk '/Li/ {print $0}' score.txt (只要这一行里有 "Li" 就打印)
- == 等于 $2 == 100 (分数正好 100)
- != 不等于 $2 != 0 (分数不是 0)
- > / < 大于 / 小于 $2 > 60 (及格)
- ~ 匹配正则 $1 ~ /^Z/ (名字以 Z 开头)
- !~ 不匹配正则 $1 !~ /a/ (名字里没字母 a)
- && 与 都满足
- || 或 二选一
- ! 非 对逻辑值取反
- >= 大于等于
- <= 小于等于
- 如果比较的是字符则需要加双引号:$1=="qweq"
正则表达式
- 元字符是正则表达式里一类具备特殊含义的专用字符
- 元字符 功能 示例 解释
- ^ 行首定位符 /^root/ 匹配所有以root开头的行
- $ 行尾定位符 /root$/ 匹配所有以root结尾的行
- . 匹配任意单个字符 /r..t/ 匹配字母r,然后两个任意字符,以t结尾
- * 匹配0个或多个前导字符 /a*ool/ 匹配0个或多个a之后跟着ool
- + 匹配1个或多个前导字符 /a+b/ 匹配1个或多个a加b的行
- ? 匹配0个或1个前导字符 /a?b/ 匹配b或ab的行
- [ ] 匹配指定字符组内的任意一个字符 /^[abc] 匹配以字母a或b或c开头的行
- [^] 匹配不在指定字符组内任意一个字符 /^[^abc]/ 匹配不以字母a或bhuoc开头的行
- ( ) 子表达式组合 /(rool)+/ 表示一个或多个rool组合
- | 或者的意思 /(root) | B/ 匹配root或者B的行
- \ 转义字符 /a\/\// 匹配a//,\.表示查找有.的行
- x{m} x重复m次 /(root){3}/ root重复3次
- x{m,} x重复至少m次 /(root){3,}/ root至少重复3次
- x{m,n} x重复至少m次但不超过n次 /(root){5,6}/ root重复5次,不超过6次
grep:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行
- -v 显示不匹配的行,也就是反选
- -n 显示匹配行以及行号
- -i 不区分大小写
- -c 统计匹配出来的行数
- -E 使用扩展的egrep命令(使用正则表达式)
- --color=auto 为grep过滤的匹配字符串添加颜色
- -w 只匹配过滤的字符,多一点少一点都不行,只有和要求的字符一样才会被过滤出来
- -o 只输出匹配的内容
- 需要加上-E或使用egrep
- [ ] 匹配括号中的所有字符,只要包含其中一个则过滤出来
- \d 等同于 [0 - 9],用于匹配数字
- \w 匹配字母、数字以及下划线,[a - zA - Z0 - 9_ ]
- \s 匹配空格、制表符、换页符等空白字符
- | 为或匹配模式,表示匹配 a 或者 b
- {n} 表示前导字符重复 n 次
- {n,} 表示前导字符至少重复 n 次
- {n,m} 表示前导字符至少重复 n 次但不超过m次
sed工作原理:读取 -> 处理 -> 输出
- 当 sed 开始运行,它会逐行读取文件内容。每读取一行,就将这一行存入一个临时缓存区,这个缓存区被称为模式空间
- 在模式空间中,sed 会根据用户指定的编辑命令对该行内容进行处理
- 处理完模式空间中的内容后,sed 会把处理后的行发送到屏幕上显示(除非使用了特定选项,如-n取消默认输出)
- 只要模式空间里还有东西,就会打印出来
sed分隔符
- 场景 推荐分隔符 示例
- 新旧字符串无特殊字符(纯文字) /(默认) sed 's/hello/world/' file.txt
- 新旧字符串包含 /(如网址、路径) +/#/@ sed 's+ /usr/local + /opt +' file.txt
sed的使用模式(可以搭配正则表达式一起使用,但是复杂的正则表达式则需要-r选项扩展)
- 命令行模式(最常用的一种模式)
- 特点:适合简单的操作(如单行替换、删除)。
- 格式:sed [选项] '命令' 文件名 如果需要引用变量,则需要使用双引号
- ‘n命令’表示在第n行执行
- ‘n,m命令’表示在n到m行执行
- -e:多项编辑 #当需要对输入行应用多条 sed 命令时使用该选项
- sed -e 's/hello/hi/' -e '/sed/d' test.txt 此命令先执行 s/hello/hi/ 将 hello 替换为 hi,再执行 /sed/d 删除包含 sed 的行
- -n:取消默认的输出 #通常情况下,sed 会输出处理后的每一行。而使用 -n 选项能取消默认输出,
- 只有在使用 p 命令时才会输出指定的行
- sed -n '/world/p' test.txt 由于使用了 -n 选项,只有匹配到 world 的行才会被打印出来
- -f:指定sed脚本的文件名称 #若有多个 sed 命令,可将它们写入一个脚本文件,然后用 -f 选项
- 指定该文件,这样可以使复杂的 sed 操作更易于管理和维护。
- sed -f script.sed test.txt
- -r:使用扩展正则表达式 #默认情况下,sed 使用基本正则表达式。使用 -r 选项可以使用
- 扩展正则表达式
- sed -r '/^[a-zA-Z]/d' test.txt
- -p:打印行 #-p 选项通常和 -n 一起使用,用于打印匹配的行
- sed -n '/example/p' test.txt
- -d:删除行 #该选项用于删除匹配的行
- sed '/world/d' test.txt
- -i:修改文件 #不加-i则只会输出修改的效果但不会修改文件
- -i.bak #将源文件备份一份后修改
- 特殊命令
- i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行
- sed '2ixxx' a.txt #第二行上面添加数据
- a\ 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行
- sed '$a99999' a.txt #最后一行下面添加数据
- sed 'a99999' a.txt #每一行下下面添加数据
- sed '/A/ a B' #在搜索到的A下面插入B,如果有多个A则会插入多个B
- c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行 整行替换
- r 从文件中读取到的内容再输出输入行
- sed '3r /etc/hosts' 2.txt #将/etc/hosts文件中的数据输入到2.txt文件的中从第三行开始
- w 将所选的行写入文件(另存为
- sed '/[0-9]\{4\}/w a.txt' 2.txt #将2.txt中查找包含4个数字的行,并将其写入到文件a.txt中
- s:用一个字符串替换另一个,默认每行第一个匹配字符串替换
- sed -n 's/root/ROOT/p' 1.txt #将带有root字段的行第一个root改为ROOT
- sed 's/[/:\.]//gp' a.txt #删除文件中所有的/ : .
- g:进行全局替换 #将每一行匹配到的所有字符进行替换
- sed -n 's/root/ROOT/gp' 1.txt #将带有root字段的所有行的所有root改为ROOT
- =:打印行号
- sed -n '/bash$/=' passwd #打印以bash结尾的行的行号
- &:保护被替换内容
- sed -n 's/^root/#&/p' a.txt #使用“&”符号保留root,在root之前添加注释号
- 脚本模式(编写shell脚本)
系统安全及应用
特殊的权限:s权限、t权限
特殊的权限:s权限、t权限
- suid(set user ID)
- 是一种特殊权限,仅设置在可执行文件中,而且仅在执行过程中有效
- 让普通用户在执行一些特定的二进制程序时,可以临时具有该文件的属主权限
- suid权限可以使用数字表示,4表示添加(chmod 4755 文件 或者chmod u+s 文件)
- chmod u+s 文件:仅添加 SUID 特殊权限,不改变文件原有基础权限,显示s
- chmod 4755 文件:强制设置 SUID + 基础权限 755(覆盖原有基础权限),显示s
- 大写S是失效的 SUID、小写s是生效的 SUID(当所有者没有执行权限的时候就会显示S)
- sgid(set group ID)
- 当给文件设置GUID位时,意味着执行文件的任何用户都将拥有与文件组所有者相同的权限
- 当GUID权限应用于目录时,在此目录中创建的所有子目录和文件将获得与主目录相同的组所有权(而
不是创建文件和目录的用户的组所有权)
- 当使用samba、ftp等文件服务器时,保证了不管任何人上传的目录或者文件属主和属组都是上层目录
- 可以使用chmod g+s 或者 chmod 2xxx 授权
- sticky(粘着位)
- Sticky Bit 通常用于共享目录
- Sticky Bit 可以确保每个用户只能删除或修改自己创建的文件,而不能随意删除或修改其他用户的文
件,从而保证了文件的安全性和独立性。
- 可以使用 chmod o+t 来添加 Sticky Bit 权限,chmod o-t 来去除 Sticky Bit 权限。
使用getfacl、setfacl设置权限
- getfacl:用于获取文件或目录的访问控制列表(ACL)(查看)
- -R:作用是递归地显示指定目录及其子目录下所有文件和目录的 ACL 规则。不过它并不会显示父目录的 ACL 规则
- setfacl:用于设置文件或目录的访问控制列表(ACL),ACL 可以让你对文件或目录的访问权限进行更细致的控制,除了传统的所有者、
所属组和其他用户的权限之外,还能为特定用户或组设置权限。(设置)
- -m:用于修改或添加 ACL 规则。可以针对特定的用户(u:)、组(g:)等设置权限
- 例:setfacl -m u:lisi:rw /data
- 设置acl,用户lisi在/data只有读写权限
- -x:用于删除指定的 ACL 条目
- -d:用于设置默认 ACL。当在一个目录上设置了默认 ACL 后,该目录下新创建的文件和子目录会继承这个默认 ACL,
但不会对已存在的文件和子目录的 ACL 进行修改
- -R:用于递归操作
设置密码有效期
- 仅针对新创建的用户有效
- 针对已有用户使用chage 命令设置
- chage -M 天数 用户 #修改最长有效期
- chage -d 0 #表示下次登录时必须修改密码
- 文件中其他配置项
- PASS_MAX_DAYS 20 #密码最长使用期限
- PASS_MIN_DAYS 0 #密码最短使用期限
- PASS_MIN_LEN 5 #密码最小字符
- PASS_WARN_AGE 7 #密码临近多久到期时发出警告
修改文件属性
- chattr:修改文件属性
- i:添加 i 选项表示不能对文件做任何的修改、删除等操作,仅有root可以取消锁定
- +i表示锁定,-i表示解锁
- lsattr:查看文件属性
用户切换和提权
- su命令切换用户,su - 用户:切换用户,“-”表示连同shell环境一起切换
- su 命令:这种方式属于非登录式切换,不会执行目标用户的登录脚本
- su - 命令:属于登录式切换,会执行目标用户的登录脚本
- 可以通过文件限制用户是否可以使用 su 命令
- wheel组
- 是一个特殊的系统用户组,组中用户拥有部分root的功能和权限
- 主要用来归纳一些特殊的系统用户,用来对服务器进行一些日常管理以及高级操作
- 加入wheel组
- usermod -aG wheel 用户名 -a:追加附属组,不覆盖原有组 -G:指定附属组
- gpasswd -a 用户名 wheel
- /etc/pam.d/su文件:可插入式身份验证模块
- auth required pamwheel.so useuid:允许wheel组中的用户登录
- 也就是当修改su文件后,只有加入到wheel组中的用户才可以使用su
- sudo用户提权(sudo -l 查看当前用户拥有哪些root权限)
- 用户提权命令,服务器中一般都在使用普通用户完成着日常管理,那么无法避免需要完成一些高级操作,当普通用户
没有执行权限时,必须使用sudo命令来利用root的身份完成操作
- 使用visudo命令或者 vim /etc/sudoers(通常只有只读权限,无法修改)、sudoedit /etc/sudoer进入文件中为普通用户、组授权
- visudo:是专门为编辑 sudoers 文件而生的专用命令(系统自带,为安全而生)
- 核心保命功能:自动语法校验 + 保存时检查错误
- vim /etc/sudoers:是用普通文本编辑器直接打开编辑(无任何安全校验)
- 无任何语法校验,改错即翻车,无法挽回
- 通常sudoers默认只有只读权限,想改就要加权限
- sudoedit /etc/sudoer:是通过 sudo 的安全机制,调用编辑器编辑 sudoers(本质是visudo的安全平替)
- 同样会做完整的语法校验,sudoedit 必须是普通用户提权执行
- root ALL=(ALL) ALL
- 用户 ALL=具体的命令(也就是绝对路径下的命令文件夹,如/usr/bin/passwd或/usr/sbin/fdisk)
禁止普通用户登录
- touch /etc/nologin:拒绝普通用户登录,想要恢复直接删除文件即可(即只要存在文件普通用户就无法登录)
远程访问和控制
SSH账户验证分为密码认证和密钥对认证,加密算法主要分为两种
SSH账户验证分为密码认证和密钥对认证,加密算法主要分为两种
- 对称加密算法(DES):加密速度、传输速度快,效率更高,安全性偏低
- 发送方使用密钥将明文数据加密成密文,然后发送出去
- 接收方收到密文后,使用同一个密钥,将密文解密成明文进行读取
- 非对称加密算法(RSA、DSA):公加私解,安全性高,但是加密速度、传输速度较慢
- 发送方使用接收方发送过来的公钥,将明文数据加密为密文,然后向外发出
- 接收方收到密文后,使用自己的私钥将密文数据解密进行读取
SSH服务端配置:/etc/ssh/sshd_config
- Port 22:指定端口号
- Protocol 2:定义版本号,默认是版本二,支持非对称加密等功能
- ListenAddress 192.168.1.1:监听IP地址
- UserDNS no:禁止反向解析,反向解析为了防止假冒的IP连接服务器,会把IP解析成域名,查看IP是否是伪造的;关闭后加快了ssh的连接
- PermitRootLogin no:禁止root用户登陆
- PermitEmptyPasswords no:禁止空密码登录
- LoginGraceTime 2m:登陆时间
- MaxAuthTries 6:重试次数
- AllowUsers jerry tom admin@192.168.1.1:允许登入的用户列表,用户之间使用空格分隔,不允许和DenyUsers同时使用
- DenyUsers 用户名 用户名@地址:拒绝用户登录,拒绝用户从某个地址登录
- PasswordAuthentication yes:开启密码验证登陆
- PubKeyAuthentication yes:开启密钥对登陆
- AuthorizedKeysFile .ssh/authorized_keys:服务端口公钥文件存放位置
登陆ssh的验证方式
- 密码验证
- 使用服务器的本地用户身份登陆验证
- 对于客户端而言使用简单
- 对服务器而言防御力较弱,有被暴力破解的风险
- 密钥对验证
- 要求提供匹配的密钥信息才能通过验证
- 客户机生产一对密钥,然后将公钥传到服务器的指定位置,远程登陆时,系统使用私钥、公钥进行加密解密
- 由于不需要密码,所以增强了远程管理的安全性
SSH远程登入
- ssh user@host = ssh -l user@host :指定连接用户,不指定使用当前登录的用户身份登录对方
- -p:指定端口
SSH密码登陆验证的步骤
- 客户端向服务器发送一个登陆请求
- 服务器把自己的公钥发给客户端
- 客户端使用服务器发送过来的公钥把自己的密码进行加密,并且发送给SSH服务端
- 服务端收到后使用私钥进行解密
- 将解密的密码和本地/etc/shadow文件中的密码对比认证
- 认证成功则返回登陆结果,并且发送一个随机回话口令给客户端,这个口令用于后期两台主机进行数据传输时临时加密的口令
远程复制文件、数据(scp)
- scp user@host:/aaa/file /root 将对方服务器中的/aaa/file文件复制到本地的/root中
- scp file1 user@host:file2 将本地文件拷贝到远程
- -r:递归拷贝目录
- -P:指定服务器端口
密钥登录步骤
- ssh-keygen -t rsa 客户端使用命令生成密钥对并且指定加密算法,默认存放在当前用户的宿主下
- 服务器端 密钥对 公钥存放文件:/root/.ssh/authorized_keys
- scp .ssh/id_rsa.pub root@192.168.62.129:/tmp/ 使用scp命令将公钥文件上传到服务端
- mv /tmp/id_rsa.pub /home/aaa/.ssh/authorized_keys 服务端将公钥文件存储到需要使用密钥对登陆的用户的宿主目录的指
- ssh-copy-id root@192.168.247.34 自动把公钥传到对方机器 + 自动放到正确位置 + 自动配权限 执行完就可以免密登录
定目录下,并且修改文件名称
- ps:主机A想要登录主机B,主机A生成密钥,然后通过scp将密钥发送给主机B,然后主机B将密钥放到对应用户的宿主目录下,
通常情况下在宿主目录没有.ssh目录需要自行创建一个.ssh密钥的名字可以在/etc/ssh/sshd_config 中修改,需要一致才会匹配密钥对
- 密钥对登陆优化步骤
- 可以将上传密钥和移动密钥修改名字步骤进行简化
- ssh-copy-id -i 公钥文件 user@host
- 验证密码后,会将公钥自动添加到目标主机user宿主目录下的.ssh/authorized_keys文件结尾
- ssh-copy-id -i ~/.ssh/id_rsa.pub lisi@192.168.4.254(~表示宿主目录)
防火墙
核心作用
核心作用
- 是网络数据包的安检员,阻止未经授权的访问,保护网络 / 主机安全
防火墙的分类
- 逻辑防火墙和物理防火墙
- 这是从“存在形态”划分的两大类,前者是“规则 / 软件层面”,后者是 “实体 / 硬件层面”
逻辑防火墙:是一套安全策略或软件,又分为网络防火墙和主机防火墙两种。没有实体,靠规则 / 程序实现
- 网络防火墙
- 保护整个网络的边界
- 隔离风险区域(如互联网)和安全区域(如公司内网)所有进出内网的流量必须经过它的检查
- 主机防火墙
- 保护单台独立的主机
- 只监控这台主机的进出数据包,不管整个网络
物理防火墙:从实现载体划分的,对应我们日常说的硬件防火墙和软件防火墙,前者是专用设备后者是电脑上的软件。有实体形态,分硬件和软件
- 硬件防火墙
- 独立的物理设备(像一个带芯片的盒子),有自己的专用系统和资源
- 不占用服务器 / 电脑的 CPU、内存 → 性能强、稳定性高、安全性好
- 软件防火墙
- 安装在普通主机上的程序(比如 Windows 防火墙、Linux 的 iptables)
- 成本低,不用额外买硬件 → 但会占用主机的系统资源
- 物理防火墙是逻辑防火墙的实现工具
iptables防火墙(软件主机防火墙)
- 是一个Linux内核防火墙工具,用于配置和管理Linux系统上的网络数据包过滤规则
- 通过定义一系列的规则来控制网络数据包的传输,这些规则可以基于源IP地址、目标IP地址、传输协议(TCP、UDP等)、
端口号等条件进行匹配
- 严格遵守,自上而下顺序匹配,匹配即停止
- 默认是允许所有
iptables的表、链结构
- 在 Linux 系统中,iptables 通过表(tables)、链(chains)以及规则(rules)协同工作,实现对数据包精细且全面的管理
- iptables中的链总共分为 5 种
- INPUT链:处理进入本机的数据包。
- OUTPUT链:处理由本机发出的数据包。
- FORWARD链:处理经过本机的数据包,例如,路由器接收到一个目的地址不是自己的数据包,这个数据包会被送
- 到FORWARD链进行处理
- PREROUTING链:处理路由决策之前的数据包,通常用于修改目的地地址。
- POSTROUTING链:处理路由决策之后的数据包,通常用于修改源地址
- 在iptables中共用 4 张表
- filter表:主要用于确定是否放行该数据包,也就是进行包过滤。同样也是默认处理的表
- nat表:用于修改数据包中的源、目标IP地址或端口,实现网络地址转换的功能
- mangle表:表主要用于对数据包的 IP 首部信息进行修改(TTL,TOS:Type of Service,服务类型)
- raw表:raw 表的主要作用是决定数据包是否要进行状态跟踪
- filter表可以使用的链:INPUT,FORWARD,OUTPUT
- nat表中可以使用的链:PREROUTING,OUTPUT ,POSTROUTING,INPUT
- mangle 表中可以使用的链:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
- raw表中可以使用的链:PREROUTING,OUTPUT
iptables的简单命令
- -L:查看规则 -n:以数字形式显示地址,端口等信息 -t:指定表名 -F:清空规则 --line-numbers:显示行数
iptables语法规则
- iptables [动作选项] [ -t 表名 ] [ -l 链名 ] [ -p 条件匹配 ] [ -j 控制类型 ]
- 动作选项
- -A:追加 (Append) 到末尾
- -I:插入 (Insert) 到开头或指定位置
- -D:删除 (Delete) 某条规则
- -L:列出 (List) 现有规则
- -F :清空所有规则(规则删除,防火墙失效)
- -Z:清空流量计数(规则还在,只是统计归零)
- 匹配条件
- -p :指定协议 (Protocol),例如 tcp、udp、icmp
- -s :指定源地址 (Source IP),例如 -s 192.168.247.32
- -d :指定目的地址 (Destination IP),例如 -d 192.168.247.100
- -o:指定网卡。例如 -o ens33
- --dport :指定目标端口 (Destination Port),例如 --dport 22
- --sport :指定源端口 (Source Port),例如 --sport 8080
- 执行目标
- -j ACCEPT :允许数据包通行
- -j REJECT :拒绝数据包通过,会给源主机返回拒绝提示
- -j DROP :丢弃数据包,无任何回应(静默拒绝)
- -j LOG :记录数据包日志信息,记录后继续匹配下一条规则
- 额外参数
- -P :设置链的默认策略 (Policy),例如 -P INPUT DROP(默认是ACCEPT)
- -n :查看规则时,不解析 IP 为域名,纯数字显示、提速
- --line-numbers :列出规则时,显示规则行号(删除规则必备)
- 常用的显式匹配条件
- 多端口匹配:-m multiport --sport 源端口列表-m multiport --dport 目的端口列表
- -m multiport --dport 21,22,80或1:888(表示1到888号端口)
- IP范围匹配:-m iprange --src-range | --dst-range IP范围
- -m iprange --src-range 192.168.4.21-192.168.4.28
- MAC地址匹配:-m mac --mac-source MAC地址
- 状态匹配:-m state --state 连接状态
- iptables-save > /etc/sysconfig/iptables #保存配置
- iptables-restore < /etc/sysconfig/iptables #重载配置
- 例子:iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 放行所有 TCP 22 端口流量
- iptables -A INPUT -s 192.168.1.100 -j DROP # 丢弃来自该源 IP 的所有流量
- iptables -A INPUT -p icmp -j REJECT # 拒绝所有 ICMP 协议(禁止 ping 本机)
- iptables -A INPUT -s 192.168.247.32 -p tcp --dport 80 -j ACCEPT #仅允许源IP通过80端口
- 当不指定表名时,默认指定filter表
- 不指定链名时,默认指表中的所有链
- 除非设置链的默认策略,否则必须指定匹配条件
iptables地址转换
- SNAT
- iptables -F #清空条目
- iptables -t nat -F #清空nat表的条目
- echo 1 > /proc/sys/net/ipv4/ip_forward #临时开启路由转发功能
- cat /proc/sys/net/ipv4/ip_forward #查看是否开启成功
- vim /etc/sysctl.conf #永久开启路由转发功能
- net.ipv4.ip_forward = 1
- sysctl -p #重载配置文件
- iptables -t nat -I POSTROUTING -s 来源网段 -o 出口网卡 -j SNAT --to-source 转换的地址
- 例子 iptables -t nat -I POSTROUTING -s 192.168.1.0/24 -o ens37 -j SNAT --to-source 222.222.222.1
- 凡是来自 192.168.1.0 网段、并且准备从 ens37 出去的包,把它的源 IP 改成 222.222.222.1
- DNAT
- iptables -t nat -I PREROUTING -d 访问的地址 -p tcp --dport 访问的端口 -j DNAT --to-destination 计划访问到的地址
- 例子iptables -t nat -A PREROUTING -d 192.168.160.3 -p tcp --dport 8080 -j DNAT --to-destination 192.168.64.134:80
- 访问160.3的所有流量 然后他的端口是8080的我都把他转成192.168.64.134:80
- (也就是将服务器的地址还有端口都映射到192.168.160.3和8080端口)
firewalld防火墙(软件主机防火墙)
- 是 iptables 的上层管理工具
- 支持运行时临时规则和永久规则,模块化配置,无需清空原有规则,兼容性更强
Zone(区域)firewalld 的灵魂,预定义安全策略集合,不同区域对应不同信任等级
- public :默认区域,谨慎信任,仅放行指定服务 / 端口,适用于云服务器、外网环境
- internal:内网区域,较高信任,适用于办公内网、局域网环境
- trusted :完全信任,放行所有流量,适用于本机、实验环境
- drop :直接丢弃所有数据包,无任何回执,适用于防扫描、高安全场景
- block :丢弃数据包并回复拒绝提示,适用于明确拒绝访问场景
- Service(服务)—— 内置的「端口 + 协议」集合,比直接放行端口更规范
- 本质:一组预定义的端口、协议配置(如 http=80/tcp,ssh=22/tcp)
- 优势:便于管理,生产环境推荐优先使用服务而非裸端口
- 内置服务路径:/usr/lib/firewalld/services/ 或 /etc/firewalld/services/
- runtime :立即生效,重启 firewalld / 服务器后失效(临时配置)
- permanent:配置后不立即生效,需执行重载命令(firewall-cmd --reload),重启后保留(永久配置)
核心查看命令
- firewall-cmd --list-all #查看默认区域的所有配置
- firewall-cmd --list-all --zone=internal #查看指定区域的所有配置
- firewall-cmd --get-zones #查看所有可用区域
- firewall-cmd --get-default-zone #查看默认区域
- firewall-cmd --get-services #查看内置服务列表
- firewall-cmd --list-ports #查看已放行的端口
- firewall-cmd --list-services #查看已放行的服务
Zone 详情字段解释(以 public 区域为例)
- target: default # 区域默认动作,未匹配规则时执行,默认 REJECT
- icmp-block-inversion: no # ICMP 阻断反转:no = 仅阻止指定 ICMP;yes = 仅允许指定 ICMP
- interfaces: # 绑定当前区域的网卡(空则未绑定,未指定区域的网卡默认归 public)
- sources: # 绑定当前区域的源 IP / 网段(空则无限制)
- services: dhcpv6-client ssh # 放行的内置服务,对应固定端口
- ports: # 放行的自定义端口(格式:端口 / 协议,如 8080/tcp)
- protocols: # 放行的传输协议(如 tcp、udp、icmp)
- masquerade: no # 是否开启 IP 伪装(SNAT),做网关 / 路由时需设为 yes
- forward-ports: # 端口转发规则(如将 80 转发到 8080)
- source-ports: # 放行的源端口(较少使用)
- icmp-blocks: # 阻断的 ICMP 类型(如 echo-request 即 ping 请求)
- rich rules: # 富规则,用于精细化访问控制(如按 IP 限制服务)
高频配置命令
- firewall-cmd --reload 重载规则(使 permanent 配置生效)
- firewall-cmd --add-port=80/tcp 临时放行 80/tcp 端口(默认区域)
- firewall-cmd --permanent --zone=public --add-port=9000/tcp 永久放行 9000/tcp 端口(public 区域)
- firewall-cmd --permanent --zone=public --add-port=1514/udp 永久放行 1514/udp 端口(public 区域)
- firewall-cmd --permanent --zone=public --remove-port=9000/tcp 移除已放行的端口(永久)
- firewall-cmd --add-service=http 临时放行 http 服务(默认区域)
- firewall-cmd --permanent --zone=public --add-service=https 永久放行 https 服务(public 区域)
- firewall-cmd --permanent --zone=public --remove-service=http 移除已放行的服务(永久)
- firewall-cmd --add-source=192.168.31.100/32 --permanent --zone=internal 永久将 192.168.31.100/32 绑定到 internal 区域
- firewall-cmd --permanent --zone=internal --add-interface=eth0 永久将网卡 eth0 绑定到 internal 区域
- firewall-cmd --set-target=DROP --zone=public --permanent 方式 1:public 区域设为 DROP 目标(永久)
- firewall-cmd --add-icmp-block-inversion --permanent 方式 2:开启 ICMP 阻断反转(永久)
- firewall-cmd --zone=public --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.10 service name=ssh accept'
- 仅允许 192.168.1.10 访问 SSH 服务(永久,public 区域
- firewall-cmd --zone=public --permanent --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port protocol=tcp port=80 accept'
- 仅允许 192.168.1.0/24 网段访问 80/tcp 端口(永久,public 区域)
- firewall-cmd --zone=public --permanent --add-rich-rule='rule family=ipv4 source address=1.2.3.4 reject'
- 拒绝 1.2.3.4 的所有流量(永久,public 区域,有返回提示)
- firewall-cmd --zone=public --permanent --add-rich-rule='rule family=ipv4 source address=5.6.7.8 drop'
- 丢弃 5.6.7.8 的所有流量(永久,public 区域,无返回)
YUM仓库服务与PXE网络装机
yum的特点
yum的特点
- 基于RPM包构建的软件更新机制
- 可以自动解决依赖关系
- 所有软件包由集中的YUM软件仓库提供
yum仓库的提供方式
- FTP服务:ftp://......
- HTTP服务:http://......
- 本地目录:file:///......
部署基于httpd和vsftpd的yum仓库
- 在yum源服务器
- mount /dev/cdrom /media
- yum -y install httpd
- cp -rf /media/* /var/www/html # 递归+强制将光盘内所有文件复制到httpd的默认网站根目录
- systemctl start httpd
- yum -y install vsftpd
- cp -rf /media/Packages/* /var/ftp/pub/ # 递归+强制将光盘内的所有rpm软件包复制到vsftpd默认共享目录
- yum -y install createrepo # 自动安装仓库索引生成工具,用于生成yum仓库的元数据索引
- createrepo -pdo /var/ftp/pub/ /var/ftp/pub/ # 为ftp共享目录下的rpm包生成yum仓库索引;
- -p保留完整路径,-d包含详细描述,-o指定索引输出目录
- 在客户机的本地yum文件中
- baseurl=ftp://服务器地址/pub/
- baseurl=http://服务器地址/media
- yum list [软件包名称] #查看软件包
- yum info [软件包名称] #查看包详细信息
- yum search 关键字 #通过关键字查找软件
- yum remove 软件名称 #卸载软件
- yum update 软件名称 #升级软件
PXE网络装机工作过程:PXE是Preboot Execution Environment的缩写,开机前的执行环境
- PXE客户机发送DHCP请求,向服务器申请IP地址
- DHCP服务器响应PXE客户机的请求,自动从地址池中分配一个IP地址给客户机,并且告知客户机:TFTP(简单文件传输协议)服务器
的IP地址以及PXE引导程序文件pxelinux.0的位置
- PXE客户端向服务器发送pxelinux.0引导程序文件的请求
- TFTP响应客户端的请求,并且将pxelinux.0文件传输给客户机
- 客户机通过网络启动到系统安装界面
- 客户机向服务器发起获取系统安装文件的请求
- 服务器响应请求,并且通过网络传输文件
- 客户机进入系统安装界面,用于需要手动来完成系统安装
装机流程
- 需要DHCP 服务器、TFTP 服务器、安装源服务器(HTTP/FTP/NFS 等)三项核心服务
- 搭建本地yum源
- [media-local]
- name=CentOS-7-Media
- baseurl=file:///mnt/cdrom
- gpgcheck=0
- enabled=1
- 安装相关软件
- yum -y install xinetd tftp tftp-server dhcp vsftpd syslinux
- xinetd:超级守护进程,它是一个管理其它提供网络服务进程的进程,常驻内存。这里主要用来管理tftp
- syslinux:是一个功能强大的引导加载程序,而且兼容各种介质。它的目的是简化首次安装Linux的时间,并建立
- 修护或其它特殊用途的启动盘。这里主要提供pxelinux.0引导文件
- 配置vsftp服务
- mkdir -p /var/ftp/centos7 # 创建ftp共享目录,用于存放完整的系统镜像文件
- mount /dev/cdrom /media
- cp -a /media/* /var/ftp/centos7 # 归档复制光盘内所有文件到ftp目录,-a=cp -r+p+d,保留权限/属性/软链接
- systemctl start vsftpd
- .discinfo和.treeinfo这两个文件必须要,并且是隐藏,有可能cp不完全,需要检查
- ls -la /var/ftp/centos7 # 查看隐藏文件是否存在
- 配置dhcp服务设置
- vim /etc/dhcp/dhcpd.conf
- subnet 192.168.160.0 netmask 255.255.255.0 { #分配的客户端网段
- range 192.168.160.20 192.168.160.30; # 分配给客户端的IP范围
- next-server 192.168.160.19; # 指定TFTP服务器的IP地址(就是服务器IP地址,核心参数)
- filename "pxelinux.0"; # 指定PXE装机的核心引导文件名,固定为pxelinux.0
- }
- dhcpd -t # 补充:检查dhcp配置文件语法是否正确,无报错则继续,有报错则修改
- systemctl start dhcpd
- systemctl enable dhcpd
- 配置tftp服务
- vim /etc/xinetd.d/tftp
- service tftp
- {
- socket_type = dgram (默认)
- protocol = udp (默认)
- wait = yes (默认)
- user = root (默认)
- server = /usr/sbin/in.tftpd (默认)
- server_args = -s /tftpboot #修改tftp路径,固定
- disable = no #修改是否启动tftp 固定
- per_source = 11 (默认)
- cps = 100 2 (默认)
- flags = IPv4 (默认)
- }
- mkdir -p /tftpboot/pxelinux.cfg
- cp /usr/share/syslinux/pxelinux.0 /tftpboot/
- cp /media/isolinux/isolinux.cfg /tftpboot/pxelinux.cfg/default
- chmod 644 /tftpboot/pxelinux.cfg/default
- cp /media/isolinux/* /tftpboot
- vim /tftpboot/pxelinux.cfg/default
- append initrd=initrd.img ks=ftp://服务器地址/pub/anaconda-ks.cfg method=ftp://服务器地址/centos7
- (method是义镜像文件引导参数。ks是无人值守安装的配置文件,用于装机时找到anac这个脚本文件)
- 无人值守,在PXE环境下
- yum -y install system-config-kickstart
- vim /root/anaconda-ks.cfg
- url --url="ftp://服务器地址/centos7"
- cp -p /root/anaconda-ks.cfg /var/ftp/pub
- chmod 644 /var/ftp/pub/anaconda-ks.cfg #默认anaconda-ks.cfg的权限是600
- 所有服务配置完成后,必须关闭防火墙和 SELinux,否则会拦截 DHCP/TFTP/FTP 的端口,导致装机失败
- /var/ftp/centos7 目录下必须有 .discinfo 和 .treeinfo 两个隐藏文件,缺失则客户机无法识别镜像
- anaconda-ks.cfg 脚本的权限必须是 644,否则 ftp 匿名用户无法下载,会报failed to fetch kickstart错误
- DHCP 配置文件中的next-server必须填写本机 IP,filename必须是pxelinux.0,缺一不可
- PXE 菜单中的ks=和method=路径必须正确,IP 地址和目录名不能写错,Linux 区分大小写
rsync远程同步
Rsync 特性
Rsync 特性
- 支持拷贝特殊文件如链接文件,设备等。
- 可以有排除指定文件或目录同步的功能,相当于打包命令tar的排除功能。
- 可以做到保持源文件或目录的权限,时间,软硬链接,属主,组等属性均不改变 -p.
- 可以实现增量同步,即只同步发生变化的数据,因此数据传输的效率很高,tar -N.
- 可以使用rcp,rsh,ssh,等方式来配合传输文件(rsync本身不对数据加密)
- 可以通过soket(进程方式)传输文件和数据(服务端和客户端)*
- 支持匿名的或认证的(无需系统用户)的进程模式传输,可实现方便安全的进程数据备份及镜像
- 可以用于同步阿里云的yum仓库,更新内网的yum仓库的软件包
配置rsync源服务器
- vim /etc/rsyncd.conf
- port=873 # 指定rsync端口。默认873
- uid = nobody # rsync服务的运行用户,默认是nobody,文件传输成功后属主将是这个uid
- gid = nobody # rsync服务的运行组,默认是nobody,文件传输成功后属组将是这个gid
- use chroot = no # rsync daemon在传输前是否切换到指定的path目录下,并锁定在该目录下
- max connections = 200 # 指定最大连接数量,0表示没有限制
- timeout = 300 # 链接超时时间,0表示永远不会超时
- pid file = /var/run/rsyncd.pid # 指定rsync daemon的pid文件
- lock file = /var/run/rsync.lock # 指定锁文件
- log file = /var/log/rsyncd.log # 指定rsync的日志文件,而不把日志发送给syslog
- dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 # 指定哪些文件不用进行压缩传输
###########下面指定模块,并设定模块配置参数,可以创建多个模块###########
- [webdoc] # 模块ID
- path = /var/www/html/ # 指定该模块的路径,该参数必须指定。启动rsync服务前该目录必须存在。rsync请求访问模块本质就是访问该路径。
- ignore errors # 忽略一些IO错误信息
- read only = false # 指定该模块是否可读写,即能否上传文件,false表示可读写,true表示可读不可写。所有模块默认不可上传
- write only = false # 指定该模式是否支持下载,设置为true表示客户端不能下载。所有模块默认可下载
- hosts allow = 10.0.0.0/24 # 指定允许连接到该模块的机器,多个ip用空格隔开或者设置区间
- hosts deny = 0.0.0.0/32 # 指定不允许连接到该模块的机器
- auth users = backuper # 指定连接到该模块的用户列表,只有列表里的用户才能连接到模块,用户名和对应密码保存在secrts file中,
- # 这里使用的不是系统用户,而是虚拟用户。不设置时,默认所有用户都能连接,但使用的是匿名连接
- secrets file = /etc/rsyncd.passwd # 保存auth users用户列表的用户名和密码,每行包含一个username:passwd。
- fake super = yes #给予权限
- ps:deny | allow
- 二者都不出现时,默认为允许访问;
- 只出现hosts allow: 定义白名单;但没有被匹配到的主机由默认规则处理,即为允许;
- 只出现hosts deny: 定义黑名单;出现在名单中的都被拒绝;
- 二者同时出现:先检查hosts allow,如果匹配就allow,否则,检查hosts deny,如果匹配则拒绝;如二者均无匹配,
- 则由默认规则处理,即为允许;
- 创建账号文件
- vim /etc/rsyncd_users.db
- backuper:123456
- zhangsan:123456
- chmod 600 /etc/rsyncd_users.db #保证安全性
- mkdir /var/www/html
- chown -R nobody:nobody /var/www/html
- 免交互处理
- vim /etc/server.pass
- 匿名用户密码
- chmod 600 /etc/server.pass
- 就可以在选项里加上 --password-file=/etc/server.pass来进行免交互式处理
- rsync同步操作
- rsync [选项] 匿名用户@rsync服务器IP::模块 文件或目录 #下行
- rsync -avz backuper@192.168.65.128::wwwroot /myweb
- rsync [选项] 文件或目录 匿名用户@rsync服务器IP::模块 #上行
- rsync -avz /myweb/ backuper@192.168.65.128::wwwroot
rsync命令的用法
- rsync [选项] 原始位置 目标位置
- -a:归档模式
- -r:递归模式
- -l:对于符号链接文件仍然复制为符号链接文件
- -p:保留文件的权限标记
- -t:保留文件的时间标记
- -g:保留文件的属组标记(仅超级用户使用)
- -o:保留文件的属主标记(仅超级用户使用)
- -D:保留设备文件及其他特殊文件
- -v:显示同步过程的详细(verbose)信息
- -z:在传输文件时进行压缩(compress)
- -H:保留硬连接文件
- --delete:删除目标位置有而原始位置没有的文件
- --checksum:根据对象的校验和来决定是否跳过文件
配置inotify进行监控
- 安装 inotify-tools。可以用yum也可以用二进制
- inotifywait命令的选项
- -m:表示始终监控
- -r:递归监控
- -q:--quiet的意思
- -e:指定监控的事件。一般监控的就delete(删除)、create(创建)、attrib(元数据被修改)、
- modify(写入)、close_write(打开的文件被关闭)、move(移动)
- 例子:inotifywait -mrq -e modify,create,move,delete /var/www/html
- 始终递归低调监控html是否被写入,创建,移动,删除
inotifywait触发rsync同步操作
- 使用while和read持续获取监控结果
- #!/bin/bash# 变量定义
- SRC="/data/" # 160.6 上的源目录
- DEST="zhangsan@192.168.247.55::wwwroot" # 160.5 上的目标模块
- PASS="/etc/server.pass" # 密码文件
- # 监控并执行
- # 注意:加了 --format '%w%f' 可以让输出更整洁
- inotifywait -mrq -e modify,create,attrib,move,delete --format '%w%f' $SRC | while read FILE
- do
- # 只有当没有 rsync 进程时才执行
- if ! pgrep -x "rsync" > /dev/null
- then
- echo "Detected change in $FILE, starting sync..."
- rsync -avzH --delete --password-file=$PASS $SRC $DEST
- fi
- done
lsync(inotify+rsync)
KVM
KVM
两种主流虚拟化技术
两种主流虚拟化技术
- 直接运行在硬件平台上,控制所有硬件并且管理客户的操作系统(原生架构)
- 运行在一个传统的操作系统之上,是一种应用程序的方式呈现,KVM就是这种方式(寄居架构)
KVM
- 全称是 Kernel-based Virtual Machine,翻译过来就是基于内核的虚拟机,它是 Linux 系统原生的硬件辅助虚拟化技术
- KVM需要经过修改的QEMU(模拟器)软件(qemukvm)来实现虚拟机的管理 KVM就是内核的一个模块
- 简单说就是让 Linux 内核直接变成一个虚拟化管理程序
KVM环境部署
- 要求
- 操作系统必须是64位的,系统内核大于等于2.6版本(目前Centos 7.7为3.10)
- CPU支持虚拟化Inter VT或者AMD-V技术,并且在BIOS中开启虚拟化功能
- VMware Workstation:创建虚拟机的CPU要勾选虚拟化功能“虚拟化Inter VT-x/EPT或AMD-V/RVI”
- 足够的硬盘空间
- egrep -o 'vmx|svm' /proc/cpuinfo | uniq #查询CPU是否支持虚拟化,有返回则支持vmx → Intel,svm → AMD
- yum install -y qemu-kvm libvirt libvirt-client virt-install virt-viewer bridge-utils #安装必要插件
- 组件 作用
- qemu-kvm 虚拟化引擎
- libvirt 虚拟化管理服务
- virt-install 命令行创建 VM
- virt-viewer 控制台
- bridge-utils 桥接网络
- systemctl start libvirtd #启动
- lsmod | grep kvm #检查内核模块
- 正常输出类似:kvm_intel 或 kvm_amd kvm。若只有kvm则虚拟化没有生效
- virt-host-validate #libvirt 自检
- 需要输出QEMU: Checking for hardware virtualization : PASS类似的
- virsh net-list --all #默认网络
- mkdir -p /var/lib/libvirt/iso
- 上传一个光盘文件
- virt-install \
- --name zjx \ # 指定创建的虚拟机名称,自定义即可
- --memory 2048 \ # 指定虚拟机分配的内存大小,单位MB
- --vcpus 2 \ # 指定虚拟机分配的CPU核心数,这里配置2核
- --disk path=/var/lib/libvirt/images/zjx.qcow2,size=10,format=qcow2 \ # 指定虚拟机磁盘文件路径+磁盘大小G+磁盘格式
- --location /var/lib/libvirt/iso/CentOS-7-x86_64-DVD.iso \ # 指定系统安装镜像ISO文件的绝对路径
- --network network=default \ # 指定虚拟机的网络模式,使用libvirt默认的nat网络
- --graphics none \ # 关闭图形化界面
- --console pty,target_type=serial \ # 配置串口控制台
- --extra-args "console=ttyS0,115200n8" \ # 传递内核启动参数
- --os-type linux \ # 指定虚拟机的操作系统类型为 linux 系统
- --os-variant centos7.0 # 指定虚拟机的系统发行版版本为 CentOS7.0
KVM常用命令
- virsh list #查看正在运行的虚拟机
- virsh list --all #查看所有虚拟机(包括关机的)
- virsh start test01 #启动虚拟机
- virsh shutdown test01 #正常关机(推荐)
- virsh reboot test01 #重启
- virsh destroy test01 #强制断电
- cd /etc/libvirt/qemu/ #KVM虚拟机配置文件存放路径
- virsh console test01 #进入虚拟机
- Ctrl + ](中括号) #退出虚拟机
磁盘(qcow2)
- qemu-img info test01.qcow2 #查看磁盘信息
- virsh domblklist test01 #查看虚拟机磁盘
- virsh domblkinfo test01 vda #查看磁盘使用情况
- 项目 qcow2 RAW
- 文件大小 按需增长(稀疏文件) 固定大小,立即占满磁盘
- 快照 支持 不支持
- 压缩/加密 支持 不支持
- 兼容性 主要用于 QEMU/KVM 通用性强,几乎所有虚拟化平台都支持
- 性能 略低于 RAW(但差距小) 最高性能(无元数据开销)
- 空间效率 高(节省存储) 低(浪费空间)
squid代理服务器
代理服务器
代理服务器
- 是网络信息的中转站,是个人网络和Internet服务商之间的中间代理机构,负责转发合法的网络信息
- 优点是通过缓存的方式为用户提供Web访问加速,对用户的Web访问进行过滤控制
squid
- 是应用层代理服务软件,主要提供缓存加速和应用层过滤控制的功能
- 工作机制
- 当客户机通过代理请求Web页面时,执行的代理服务器会先检查自己的缓存,当缓存中有客户机需要访问的页面,
- 则直接将缓存服务器中的页面内容反馈给客户机;如果缓存中没有客户机需要访问的页面,
- 则由代理服务器想Internet发送访问请求,当获得返回的Web页面以后,将页面数据保存到缓存中并发送给客户机
代理的基本类型
- 传统代理:代理客户端,需手动配置代理 IP + 端口,用于个人翻墙、开发调试、指定应用走代理
- 透明代理:代理客户端,零配置,完全无感知,用于企业 / 校园网审计、缓存加速、网站过滤,需要将⽹关指向代理服务器
- 反向代理:代理服务器端,零配置,完全无感知,用于网站负载均衡、隐藏真实服务器、
squid安装
- yum install -y gcc gcc-c++ gcc-gnat libgcc libgcc.i686 glibc-devel bison flex texinfo Development Tools #安装依赖
- tar -xzvf squid-4.15.tar.gz -C /usr/src/ #解压文件
- cd /usr/src/opt/squid-4.15/ 14:14 2026/1/30#进入文件目录
- ./configure \--prefix=/usr/local/squid \--sysconfdir=/etc \--enable-arp-acl \--enable-linux-netfilter \--enable-linux-tproxy
- \--enable-async-io=100 \--enable-err-language="Simplify_Chinese" \--enable-underscore \--enable-poll \--enable-gnuregex
- make && make install
- ln -s /usr/local/squid/sbin/* /usr/local/sbin/ #设置软连接
- useradd -M -s /sbin/nologin squid #创建用户
- chown -R squid.squid /usr/local/squid/var/ #修改属组
- vim /etc/squid.conf #修改配置文件
- cache_effective_user squid #添加指定程序用户
- cache_effective_group squid #添加指定账号基本组
- squid -k parse #检查配置文件语法
- squid -z #初始化缓存目录
- squid #启动squid服务
- vim /etc/squid.conf #修改配置文件
- http_access allow all #允许任意客户机使用代理
- http_port 3128 #使用3128端口
- cache_mem 64 MB #指定缓存功能所使用的内存空间大小
- reply_body_max_size 10 MB #允许用户下载的最大文件大小
- maximum_object_size 4096 KB #允许保存到缓存空间的最大对象大小
- curl -x http://代理服务器地址:端口 http://web服务器地址
- export http_proxy=http://代理服务器地址:端口
构建透明代理
- echo "1" > /proc/sys/net/ipv4/ip_forward #开启转发功能
- vim /etc/squid.conf #修改配置文件
- http_port 3129 intercept #添加透明代理
- 重启squid服务
- iptables -t nat -I PREROUTING -i ens33 -s 源网段 -p tcp --dport 80 -j REDIRECT --to 3129 #设置重定向
Nginx
Nginx文件路径
Nginx文件路径
- 主配置文件:/etc/nginx/nginx.conf
- 访问日志:/var/log/nginx/access.log
- 错误日志:/var/log/nginx/error.log
Nginx怎么解决跨域问题:浏览器要求请求的「协议、域名、端口」三者完全一致才是「同源」,否则视为跨域,会拦截响应
- 添加 CORS 响应头
- 在 Nginx 配置中,给后端接口的响应添加 Access-Control-* 系列头,明确告知浏览器允许跨域访问
- 反向代理(最优,让跨域变同源)
- 将前端和后端接口都代理到同一个域名下(浏览器认为同源),Nginx 内部转发请求到后端,彻底规避跨域问题
Nginx 基础概述:Nginx是一款高性能、轻量级Web服务软件,是一种中间件,默认端口是80
- 核心特点
- 高性能、轻量级,支持5 万并发连接(理论上最高),生产中常是2~3万,采用 epoll 模型实现高并发
- 支持热部署、低资源消耗,采用一 master 多 worker进程模型,master 进程管理配置,worker 进程处理请求
- 应用场景:静态 Web 服务器、虚拟主机、反向代理、负载均衡
nginx为什么要实现动静分离
- 静态资源 Nginx 处理比后端快 10~100 倍
- 减轻后端服务器压力,让后端只处理业务
- 浏览器缓存更方便,优化加载速度
- 架构更清晰,便于维护
nginx怎么实现动静分离
- 动静分离:就是让Nginx 干它最擅长的事
- 静态资源:HTML、CSS、JS、图片、字体、视频 → Nginx 自己直接读取本地文件返回,速度极快
- 动态资源:接口(api)、登录、查询、业务逻辑、与数据库有交互的 → Nginx 转发给后端服务(Java/PHP/Python/Node 等)
- 静态资源由nginx自身处理,动态资源转发到后端处理
- 根据文件后缀分离
- .html .css .js .jpg .png .gif .ico .woff 等 → 静态 → 直接读本地文件返回
- .php .jsp/api / 接口 → 动态 → 转发给后端服务(Java/PHP/Python/Node)
- 根据路径分离
- 静态资源统一放在/static/目录,动态资源放/api/
- server {
- listen 80;
- server_name localhost; # 你的域名
- # ======================
- # 1. 前端静态资源(动静分离)
- # ======================
- root /usr/share/nginx/html/dist;
- index index.html;
- # 前端路由模式(Vue/React History 模式必需)
- location / {
- try_files $uri $uri/ /index.html;
- }
- # 静态资源缓存优化(图片、CSS、JS 缓存 7 天)(增加了缓存,可以加快访问速度)
- location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?|svg)$ {
- expires 7d; # 缓存 7 天
- add_header Cache-Control public;
- }
- # ======================
- # 2. 后端接口转发(前后端分离)
- # ======================
- location /api/ {
- # 转发到后端服务
- proxy_pass http://127.0.0.1:8080/;
- # 必需的转发请求头
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
- }
Nginx和apache的优势区别
- Nginx 的核心优势
- 高并发、低消耗:异步非阻塞架构,处理静态资源和反向代理时性能碾压 Apache
- 配置简洁:层级化配置易于理解和维护,适合自动化运维
- 负载均衡能力:原生支持权重轮询、IP 哈希等调度算法,可直接作为负载均衡器使用
- Apache 的核心优势
- 动态请求处理:可嵌入运行 PHP 等脚本,无需额外转发进程,部署简单
- 模块生态丰富:支持海量第三方模块,功能扩展性强
- 兼容性好:支持老旧系统和各种小众功能需求,迁移成本低
Nginx 配置文件结构
- 配置文件分为5 个核心模块,从外层到内层依次生效:全局块 → events块 → http块 → server块 → location块
- 全局块
- user nginx; 指定 worker 进程的运行用户,需对网站目录有读权限
- worker_processes auto; worker 进程数,建议设为 CPU 核心数,充分利用多核性能
- events 块
- worker_connections 1024; 单个 worker 进程的最大连接数
- 理论最大并发数:worker_processes × worker_connections,反向代理场景需除以 2(客户端 + 后端连接)
- 高并发优化:设置worker_rlimit_nofile 65535;,并修改系统限制ulimit -n 65535
- http 块
- 核心配置区域,包含include mime.types(识别文件类型)、日志格式、gzip 压缩、upstream 负载均衡等
- 关键指令:sendfile on;(开启零拷贝,提升静态文件传输效率)、keepalive_timeout 65;(长连接超时时间)
- server 块
- 对应一个虚拟主机,通过listen指定端口,server_name指定域名(支持多个、通配符)
- 多站点区分:同一端口下通过server_name区分不同域名
- location 块
- 匹配请求 URI,优先级口诀:= 精准匹配 > ^~ 前缀匹配 > ~/~* 正则匹配 > 普通前缀匹配
- 常用功能:静态资源:root指定网站根目录,index指定默认首页
- 反向代理:proxy_pass转发请求到后端服务器
- 静态资源缓存:expires 7d;(设置缓存过期时间)
Nginx 常用超时参数及作用
- 参数 作用 场景举例
proxy_connect_timeout 定义 Nginx 与后端上游服务器(比如 Java Jar 服务)建立连接的超时时间 默认 60s,若后端服务启动慢,需调大,避免连接超时
proxy_read_timeout 建立连接后,Nginx 等待后端服务器返回数据的超时时间 大文件上传 / 下载、后端接口处理耗时久时,需调大(比如设为 600s),否则 Nginx 会断开连接
proxy_read_timeout 建立连接后,Nginx 等待后端服务器返回数据的超时时间 大文件上传 / 下载、后端接口处理耗时久时,需调大(比如设为 600s),否则 Nginx 会断开连接
proxy_send_timeout Nginx 向后端服务器发送请求的超时时间 后端接收请求慢时,避免发送中断
proxy_send_timeout Nginx 向后端服务器发送请求的超时时间 后端接收请求慢时,避免发送中断
client_header_timeout Nginx 等待客户端发送 HTTP 请求头的超时时间 防止客户端恶意占用连接,默认 60s 即可
client_header_timeout Nginx 等待客户端发送 HTTP 请求头的超时时间 防止客户端恶意占用连接,默认 60s 即可
client_body_timeout Nginx 等待客户端发送 HTTP 请求体的超时时间 大表单提交、文件上传时需调大
client_body_timeout Nginx 等待客户端发送 HTTP 请求体的超时时间 大表单提交、文件上传时需调大
反向代理与负载均衡
反向代理与负载均衡
- 核心原理
- Nginx 反向代理:接收客户端请求后,重新发起请求到后端节点,后端节点看到的请求源是 Nginx,而非真实客户端
- 与 LVS 区别:LVS 是转发数据包,后端节点能看到真实客户端 IP;Nginx 是应用层代理,需配置X-Real-IP传递真实 IP
- 负载均衡配置(upstream 模块)
- 常用的负载均衡算法:轮询,权重,哈希,最少连接
- 定义后端服务器池,放在 http 块内,默认调度算法为权重轮询(wrr)
- 基础配置(单纯代理只需要新建location块,然后在里面添加proxy_pass http://IP)
- upstream www_pools {
- server 10.0.0.7:80 weight=1 max_fails=2 fail_timeout=10s;
- server 10.0.0.8:80 weight=2; # 权重越高,接收请求越多
- server 192.168.1.100:80 backup; # 备份节点,主节点故障时启用
- }
- server {
- listen 80;
- server_name www.etiantian.org;
- location / {
- proxy_pass http://www_pools;
- # 传递真实IP和请求头
- proxy_set_header Host $host; #定义域名
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
- }
- upstream 参数说明
- weight 权重,默认 1,数值越大请求占比越高
- max_fails 最大失败次数,默认 1,建议 2~3 次
- fail_timeout 失败后等待时间,默认 10s
- backup 标记为备份节点
- down 标记为永久不可用节点
前后端跨域问题解决
- 当前端与后端域名不同时,会出现No 'Access-Control-Allow-Origin'错误,需在 Nginx 配置 CORS 头\
- server {
- listen 80;
- server_name your-domain.com;
- location / {
- proxy_pass http://backend_server;
- # 允许所有源跨域,生产环境建议指定具体域名
- add_header 'Access-Control-Allow-Origin' '*';
- add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
- add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type';
- # 处理预检请求
- if ($request_method = 'OPTIONS') {
- return 204;
- }
- }
- }
- 前后端分离 SPA 配置要点
- 前端路由:try_files $uri /index.html;,确保前端路由路径返回首页,由前端框架处理
- 后端 API 转发:location /api/匹配 API 请求,转发到后端服务
Nginx 服务管理
- 常用命令
- 启动: nginx
- 停止: nginx -s stop
- 重载配置:nginx -s reload
- 配置检查:nginx -t
- 服务脚本
- vim /usr/lib/systemd/system/nginx.service
- [Unit]
- Description=nginx - high performance web server
- Documentation=http://nginx.org/en/docs/
- After=network.target remote-fs.target nss-lookup.target
- [Service]
- Type=forking
- PIDFile=/usr/local/nginx/logs/nginx.pid
- ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
- ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
- ExecReload=/bin/kill -s HUP $MAINPID
- ExecStop=/bin/kill -s QUIT $MAINPID
- PrivateTmp=true
- [Install]
- WantedBy=multi-user.target
- chmod +x /usr/lib/systemd/system/nginx.service
- systemctl daemon-reload
- 执行完后就可以正常时systemctl 选项 nginx
LNMP平台搭建
- 环境:nginx,mysql,php(编译时需要加上--enable-fpm)
- 配置php-fpm
- cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf #复制配置文件并添加启动服务
- cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf
- cp /usr/src/php-7.4.16/php.ini-development /usr/local/php/php.ini
- cp /usr/src/php-7.4.16/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
- chmod +x /etc/init.d/php-fpm
- chkconfig --add php-fpm
- echo 'PATH=/usr/local/php/bin:$PATH' >> /etc/profile #添加环境变量
- source /etc/profile
- vim /usr/local/php/php.ini #配置php.ini文件
- date.timezone = PRC //设置时区
- mysqli.default_socket = /data/mysql.sock //将php与mysql关联
- service php-fpm start #启动php-fpm
- netstat -anpt | grep php-fpm #端口为9000
- Nginx+php-fpm配置
- vim /usr/local/nginx/conf/nginx.conf
- server {
- root /var/www/html; #把root变量站点根目录定义提升上层
- location / {
- #root /var/www/html; #注释掉
- index index.php index.html; #添加默认索引
- }
- location ~ \.php$ {
- fastcgi_pass 127.0.0.1:9000; #Nginx通过本机的9000端口将PHP请求转发给PHP-FPM处理
- fastcgi_index index.php; #添加,php首页文件
- include fastcgi.conf; #Nginx调用fastcgi接口处理PHP请求
- }
- service nginx restart
- 配置wordpress
- 将wordpress配置在/var/www/html下
Tomcat和负载均衡
Tomcat
Tomcat
- Tomcat 是一款开源免费的轻量级 Java Web 应用服务器,主要用于运行 Servlet、JSP 等 Java 动态网页程序,在中小型系统和并发量
不高的场景中应用广泛。它既能独立提供 Web 服务,也能和 Nginx 配合搭建负载均衡集群,提升服务的并发能力和可用性
- 核心作用
- 处理 Java 动态请求:专门运行 Servlet、JSP 程序,是开发和调试 Java Web 项目的首选服务器
- 静态资源处理能力弱:虽然也能处理 HTML、CSS 等静态文件,但性能远不如 Nginx、Apache
- 因此生产环境中通常搭配 Nginx 使用 ——Nginx 处理静态资源,Tomcat 处理动态请求
- 核心优势
- 开源免费,无商业授权成本
- 社区活跃,与 Java 生态兼容性好
- 配置简单,支持热部署(修改项目文件后无需重启服务器即可生效)
二进制安装java
- java -version #检测是否由java,有则会显示java版本
- tar -zxvf jdk-8u261-linux-x64.tar.gz -C /usr/src
- mv /usr/src/jdk1.8.0_261 /usr/local/java
- vim /etc/profile #配置环境变量,/etc/profile是全局环境变量配置文件,编辑这个文件需要root权限
- export JAVA_HOME=/usr/local/java #指定 JDK的安装根目录
- export JRE_HOME=${JAVA_HOME}/jre #指定 Java 运行环境(JRE)的目录
- export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib #指定 Java 类加载器(ClassLoader)查找 Java 类文件(.class 文件)的路径
- export PATH=${JAVA_HOME}/bin:$PATH #将 JDK 的 bin 目录添加到系统的 PATH 环境变量中
- source /etc/profile #让刚修改的 /etc/profile 配置文件立即生效
安装tomcat
- Tomcat 基于 Java 开发,必须先安装 JDK 并配置好 JAVA_HOME 环境变量,否则无法启动
- 无需编译,直接通过 bin 目录下的脚本启动 / 关闭
- tar -zxvf apache-tomcat-9.0.48.tar.gz -C /usr/src
- mv /usr/src/apache-tomcat-9.0.48 /usr/local/tomcat
- cd /usr/local/tomcat/bin/ #进入bin目录下运行脚本启动tomcat
- ./startup.sh
Tomcat基于域名的虚拟主机配置
- vim /usr/local/tomcat/conf/server.xml
- <Host name="www.qingmei.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
- <!-- 配置虚拟目录,path="" 表示默认站点,访问路径为 http://www.qingmei.com:8080 -->
- <Context docBase="/web/webapp" path="" reloadable="false"></Context>
- </Host>
Nginx + Tomcat 负载均衡集群搭建
- 搭建两台Tomcat服务器
- 配置 Nginx 负载均衡
- vim /usr/local/nginx/conf/nginx.conf
- http { # 定义 Tomcat 节点池,默认权重轮询调度
- upstream tomcat_cluster {
- server 192.168.65.130:8080 weight=1; # 节点 1,权重 1
- server 192.168.65.131:8080 weight=1; # 节点 2,权重 1
- }
- server {
- listen 80;
- server_name localhost;
- location / { # 转发请求到 Tomcat 集群
- proxy_pass http://tomcat_cluster;
- proxy_set_header Host $host; # 传递客户端真实 IP 和请求头
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- }
- }
}
LVS负载均衡群集
LVS负载均衡群集
衡量高可用性的两个关键指标是MTBF(平均无故障时间)和MTTR(平均修复时间(或平均恢复前时间))
衡量高可用性的两个关键指标是MTBF(平均无故障时间)和MTTR(平均修复时间(或平均恢复前时间))
负载均衡集群基础
负载均衡集群基础
- 集群类型
- 负载均衡集群(LVS 所属):提升并发处理能力,减少请求延迟
- 高可用集群:保障服务不间断,避免单点故障
- 高性能运算集群:提升 CPU 算力,用于大型计算场景
- 常用负载均衡软件与硬件
- 开源软件 LVS、Nginx、HAProxy、Keepalived 成本低、可二次开发,对运维能力要求高
- 商业硬件 F5、Netscaler、Radware、A10 性能强、稳定,成本高、不可二次开发
- 负载均衡集群三层架构
- 负载调度器(Director Server):集群入口,接收客户端请求并转发至后端节点
- 服务器池(Real Server):处理实际业务请求,提供应用服务
- 共享存储:为服务器池提供统一的文件存储,保证节点内容一致性,常用 NFS
LVS 核心理论
- LVS 基本概念
- LVS:Linux Virtual Server,Linux 内核集成的四层负载均衡器,由章文嵩博士主导开发
- 核心术语
- VIP:虚拟 IP,面向用户的集群入口 IP
- DIP:调度器内网 IP,用于和后端节点通信
- RIP:后端真实服务器的 IP
- CIP:客户端 IP
- DS:Director Server,负载调度器
- RS:Real Server,后端真实服务器
- 四种工作模式
- NAT
- 原理:客户端请求到 VIP → 调度器把目标 IP (VIP)改成 RIP,发给后端 RS;
- RS 回包必须经过调度器,调度器再把源 IP(RIP) 改回 VIP,回给客户端
- 调度器修改请求报文目标 IP 为 RIP,响应报文需经调度器修改源 IP 为 VIP
- 配置简单,RS 可用私有 IP
- 调度器易成带宽瓶颈(所有请求和回应都会经过调度器) RS 网关必须指向 DIP
- 需开启内核 ip_forward
- DR(最常用)
- 原理:只改二层 MAC 地址,三层 IP 从头到尾不变
- 客户端请求 VIP,调度器把帧的目标 MAC 改成某台 RS 的 MAC,IP 还是 VIP;
- RS 收到后直接回包给客户端,不经过调度器
- 调度器修改请求报文的 MAC 地址为目标 RS 的 MAC,IP 地址不变,RS 直接响应客户端
- 性能极高,调度器仅处理请求流量
- 调度器与 RS 必须在同一二层局域网
- RS 在 lo 接口配置 VIP;需设置 arp_ignore/arp_announce 抑制 ARP 响应
- TUN 调度器给原 IP 报文封装新 IP 头,转发至 RS;RS 解封装后直接响应客户端
- 支持跨网段、跨地域部署
- 隧道封装有 CPU 开销;RS 需支持隧道协议
- RS 需配置 VIP;无需开启 ip_forward
- FULLNAT(非标准)
- 同时修改请求报文的目标 IP(VIP→RIP)和源 IP(CIP→DIP)
- 部署灵活,RS 无需和调度器同网段
- 无法直接获取客户端真实 IP;性能略低于DR
- 需借助 TCP Option 传递客户端真实 IP
- 八种调度算法
- 固定调度
- 轮询(rr)
- 按顺序循环分配请求,每个 RS 依次获取等量的客户端请求
- 各 RS 性能相近的场景
- 加权轮询(wrr)
- 给 RS 分配不同权重,权重越高,获得的请求数越多,按权重比例循环分配
- RS 性能差异较大,按权重分配请求
- 动态调度
- 最少连接(lc)
- 优先将请求分配给当前活跃连接数最少的 RS,即 “谁空闲,给谁分配”
- 连接时长不一的场景,优先分配给连接数少的 RS
- 加权最少连接(wlc)
- 结合 RS 权重和当前连接数,优先分配给[连接数/权重]比值最小的 RS,既考虑性能差异,又考虑实时负载
- RS 性能差异大,高权重 RS 承担更多连接
- 基于局部性
- 基于局部性最少连接(lblc) Cache 集群,优先分配目标 IP 最近使用的 RS
- 带复制的局部性最少连接(lblcr) Cache 集群,维护目标 IP 到 RS 组的映射
- 散列调度
- 目标地址散列(dh) 根据目标 IP 散列固定分配 RS
- 源地址散列(sh也就是source hash) 实现会话保持,同一客户端 IP 固定指向同一 RS
- 会话保持策略
- 基于源 IP 的会话保持:利用 sh 调度算法,简单但可能因 NAT 导致多用户共用同一 IP
- Cookie 插入:负载均衡器插入 Cookie 标识 RS,需客户端支持 Cookie
- 应用层会话管理:会话状态存储在共享存储(如 Redis、数据库),灵活性最高
- 会话复制:RS 间同步会话数据,内存消耗大,适合小型集群
在DR模式中
- 为什么 VIP 要配置在 RS 的回环地址
- LVS-DR 模式的核心是目标 MAC 地址替换
- 前端 Director(LVS 服务器)收到用户请求后,不会修改 IP(目标 IP 还是 VIP),只把数据包的目标 MAC 地址改成某台 RS 的 MAC 地址,然后把包发出去;
- RS 收到包后,需要识别 “目标 IP 是 VIP” 的数据包并处理,因此必须在本地配置 VIP;
- 但如果把 VIP 配置在 RS 的物理网卡(比如 eth0),会导致 RS 向外广播 “我拥有这个 VIP”,引发内网 IP 冲突(多台 RS 都有 VIP);
- 配置在回环地址(lo:0):ifconfig lo:0 192.168.1.100 netmask 255.255.255.255 up(VIP 是集群虚拟 IP),回环地址只在本机生效,不会向外广播,既让 RS 能识别 VIP 数据包,又避免 IP 冲突
- 为什么要禁用 RS 的 ARP 解析
- 正常情况下,当内网其他设备想访问 VIP 时,会发送 ARP 请求 “谁拥有 VIP这个 IP?”;
- 如果 RS 不禁 ARP,就会响应这个请求,导致内网所有访问 VIP 的流量都直接发到这台 RS,而非先到 Director(LVS),LVS 的负载均衡就失效了
LVS 实践配置
- ipvsadm 核心命令
- 清空所有规则 ipvsadm -C 初始化 LVS 配置
- 添加虚拟服务 ipvsadm -A -t VIP:Port -s 算法 例:ipvsadm -A -t 192.168.1.100:80 -s rr(使用轮询)
- 添加后端 RS ipvsadm -a -t VIP:Port -r RIP:Port -模式 -w 权重 NAT 模式用-m,DR 模式用-g
- 例:ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.20:80 -g -w 1
- 查看配置 ipvsadm -Ln -n以数字显示 IP 和端口,速度快
- 查看统计信息 ipvsadm -Ln --stats 查看包量、字节数等统计数据
- 保存规则 ipvsadm-save -n > /etc/sysconfig/ipvsadm 防止重启后规则丢失
- 恢复规则 ipvsadm-restore < /etc/sysconfig/ipvsadm 从文件恢复配置
NAT 模式集群搭建
- 环境准备
- 调度器:双网卡(外网 VIP、内网 DIP)
- 后端 RS:网关指向调度器 DIP
- 所有节点关闭防火墙和 SELinux
- 调度器配置(DS)
- 安装 ipvsadm:yum -y install ipvsadm
- 开启 ip_forward:echo "1" > /proc/sys/net/ipv4/ip_forward,永久生效需修改/etc/sysctl.conf
- 配置 ipvsadm 规则(看核心命令)(使用-m指定NAT模式)
- 配置 iptables 转发:iptables -P FORWARD ACCEPT
- 后端 RS 配置
- 安装并启动服务(如 httpd)
- 修改网关为调度器 DIP(ip route add dafault via IP(DIP) )
- 测试页面差异化(用于验证轮询效果)
- 验证:客户端多次访问 VIP,查看页面是否在不同 RS 间切换,或关闭一个服务,另一个服务可以正常启动
DR 模式集群搭建步骤(核心)
- 环境准备:调度器与 RS 在同一二层网络,所有节点关闭防火墙和 SELinux
- 调度器配置
- 安装 ipvsadm,绑定 VIP 到物理网卡子接口:ip addr add VIP/32 dev 网卡名
- 配置 ipvsadm 规则(使用-g参数指定 DR 模式)
- 关闭 ip_forward(DR 模式不需要)
- 后端 RS 配置
- 在 lo 接口绑定 VIP:ip addr add VIP/32 dev lo
- 添加路由规则:ip route add VIP dev lo
- 修改内核参数抑制 ARP 响应
- 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
- 验证
- 客户端访问 VIP,查看轮询效果
- 调度器抓包:仅能看到请求包,无响应包(响应由 RS 直接发给客户端)
NFS 共享存储配置
- NFS 作用
- 为 LVS 后端 RS 提供统一的文件存储,保证所有节点的网页、配置等内容一致
- 服务端配置步骤
- 安装软件:yum -y install nfs-utils rpcbind
- 创建共享目录:mkdir -p /data/nfs && chmod 777 /data/nfs
- 配置导出目录:编辑/etc/exports
- 添加/data/nfs 192.168.160.0/24(rw,sync,no_root_squash)
- (160网段可以访问NFS,有读写权限,同步写入,客户端root用户保留权限)
- 启动服务:systemctl enable --now rpcbind nfs-server
- 生效配置:exportfs -r
- 查看共享:exportfs 或 showmount -e
- 客户端配置步骤
- 安装软件:yum -y install nfs-utils
- 临时挂载:mount -t nfs NFS服务器IP:/data/nfs /mnt(/mnt是服务索引目录)
- 或永久挂载:编辑/etc/fstab
- 验证:在/mnt创建文件,查看服务端共享目录是否同步
LVS 高可用与架构建议
- LVS 高可用部署:搭配 Keepalived 实现调度器主备切换,避免单点故障
- 大型集群架构:LVS+Keepalived(四层) → Nginx/HAProxy(七层) → 应用服务器
- 模式选择建议
- 小规模集群、RS 与调度器同网段:优先选 DR 模式(性能最高)
- 跨网段部署:选 TUN 模式
- 低成本、简单部署:选 NAT 模式(注意带宽瓶颈)
关键注意事项
- NAT 模式必须开启ip_forward,DR/TUN 模式不需要
- DR 模式中 RS 的 ARP 抑制参数是配置成功的核心,否则会出现 VIP 冲突
- LVS 规则默认重启失效,需用ipvsadm-save保存
- NFS 共享仅适合局域网,无用户认证,生产环境可搭配权限控制或改用分布式存储
Keepalived双机热备
Keepalived
Keepalived
- Keepalived 是基于 VRRP 协议实现的高可用工具,主要用于解决 LVS 调度器单点故障问题
- 同时完成后端 RS 节点的健康检查与自动剔除,常与 LVS 搭配构建高可用负载均衡集群
核心原理
- VRRP 协议核心
- 多台服务器组成虚拟路由器,共用一个 VIP 对外提供服务
- Master 节点定期向组播地址 224.0.0.18 发送心跳包,Backup 节点监听该地址
- 当 Master 故障(心跳中断),Backup 节点会自动接管 VIP(默认3秒),实现故障切换(Failover),切换速度可低于 1 秒
- 角色与优先级
- 集群内节点分为 MASTER 和 BACKUP 两种角色,由 priority 参数决定优先级,数值越大优先级越高
- 主备节点的 virtual_router_id 必须一致,否则无法组成同一虚拟路由组
关键配置(/etc/keepalived/keepalived.conf)
- 全局配置(global_defs)
- global_defs {
- router_id LVS_DEVEL # 节点唯一标识,建议设为主机名
- }
- VRRP实例配置(vrrp_instance)
- vrrp_instance VI_1 {
- state MASTER # BACKUP 节点改为 BACKUP
- interface ens33 # 绑定 VIP 的物理网卡
- virtual_router_id 51 # 主备必须一致
- priority 100 # BACKUP 节点建议设为 90
- advert_int 1 # 心跳间隔,单位秒
- authentication { # 防止非法节点加入
- auth_type PASS
- auth_pass 1111
- }
- virtual_ipaddress {
- 192.168.64.100 # VIP 地址,可配置多个
- }
- }
- 虚拟服务器配置(virtual_server)
- virtual_server 192.168.64.100 80 {
- delay_loop 6 # 健康检查间隔
- lb_algo rr # 调度算法:rr 轮询、wrr 加权轮询等
- lb_kind DR # LVS 模式:DR / NAT / TUN
- protocol TCP
- real_server 192.168.64.138 80 { # 后端 RS 节点
- weight 1
- TCP_CHECK { # 健康检查方式:检测 80 端口
- connect_timeout 3
- }
- }
- }
LVS-DR 模式集群部署步骤
- 以 LVS+Keepalived+Nginx 架构为例,集群分为 客户端、LVS 调度器、Nginx 节点、后端 Web 节点 四层
- 环境准备
- 两台 LVS 调度器安装软件:yum install -y keepalived ipvsadm
- 所有节点关闭防火墙和 SELinux,防止拦截 VRRP 组播包
- 执行反向路径过滤优化:echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
- 实验环境
- 前置软件
- yum install -y perl perl-libs lm_sensors-libs
- 安装上传的安装包
- rpm -ivh net-snmp-libs-5.7.2-49.el7_9.4.x86_64.rpm
- rpm -ivh net-snmp-agent-libs-5.7.2-49.el7_9.4.x86_64.rpm
- rpm -ivh lm_sensors-libs-3.4.0-8.20160601gitf9185e5.el7_9.1.x86_64.rpm
- rpm -ivh keepalived-1.3.5-19.el7.x86_64.rpm
- 主备设置
- global_defs {
- router_id LVS_DEVEL
- }
- vrrp_instance VI_1 {
- state MASTER # 备机改为 BACKUP
- interface ens33 # 你的物理网卡名
- virtual_router_id 51 # 主备必须一致
- priority 100 # 备机建议设为 90
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 1111
- }
- virtual_ipaddress {
- 192.168.64.100 # 这里的 VIP 不需要加子接口名,这里是虚拟的IP 也就是会漂移的VIP
- }
- }
- # LVS 配置部分,Keepalived 会自动帮你执行 ipvsadm 命令
- virtual_server 192.168.64.100 8080 {
- delay_loop 6
- lb_algo rr # 调度算法
- lb_kind DR # 模式选择 DR
- protocol TCP
- real_server 192.168.64.138 8080 {
- weight 1
- TCP_CHECK { # 健康检查:如果 RS 的 80 端口挂了,自动踢出
- connect_timeout 3
- }
- }
- real_server 192.168.64.139 8080 {
- weight 1
- TCP_CHECK {
- connect_timeout 3
- }
- }
- }
- 后端 RS 节点配置
- ifconfig lo:0 192.168.247.100 netmask 255.255.255.255 up #在 lo:0 接口绑定 VIP,掩码设为 255.255.255.255
- echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore #抑制 ARP 广播(DR 模式关键),避免 VIP 地址冲突
- 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
脑裂问题
- Backup 节点收不到 Master 心跳,误以为其故障,导致主备同时持有 VIP,引发流量混乱
- 常见原因
- 链路故障:主备心跳线断开或交换机故障
- 防火墙拦截:未放行 VRRP 组播包(224.0.0.18)
- 配置错误:主备 virtual_router_id 不一致
- 预防方案
- 增加冗余心跳链路:用独立网卡直连主备节点,不依赖业务网络
- 编写自杀检查脚本:监控节点对外连通性(如 ping 网关),持有 VIP 但无法通信时主动释放 VIP 并停止 Keepalived
- 引入仲裁机制:多节点集群使用 Corosync + Pacemaker,基于法定人数(Quorum)决策 VIP 归属
注意事项
- 部署前需删除手动配置的 VIP,避免与 Keepalived 自动配置的 VIP 冲突
- 云环境(如阿里云)不支持组播,不建议自建 Keepalived,优先使用云厂商 SLB 服务
- 非抢占模式(nopreempt):配置后,原 Master 恢复后不会抢占 VIP,适合数据库等对切换敏感的场景
HAProxy
HAProxy
- HAProxy 是一款专注于高性能负载均衡的开源软件,支持四层(TCP)和七层(HTTP)转发
- 具备完善的健康检查、会话保持和监控能力,是构建高可用 Web 集群的核心组件
- 搭建 HAProxy 高可用,通常使用 Keepalived 实现双机热备(主备模式),通过虚拟 IP(VIP)漂移实现故障自动切换,保证负载均衡服务不中断
核心特性与工作模型
- 核心优势
- 双协议支持:四层基于 IP + 端口转发(如 MySQL、Redis),七层基于 HTTP 协议解析(可按 URL/Header 分流)
- 高效事件驱动(有请求才处理,才消耗资源):采用单线程事件循环模型,类似 Nginx,资源消耗低,能轻松应对数万并发连接
- 专业负载能力:支持丰富调度算法,健康检查精细,自带可视化监控页面,队列管理能力强
- 功能扩展性:支持 SSL 卸载、会话保持、ACL 规则控制,可作为微服务网关使用
- 事件驱动模型(对比传统服务器)
- 传统服务器(如 Apache prefork) HAProxy/Nginx 事件驱动模型
- 资源分配 一个请求占用一个进程 / 线程,阻塞等待 单线程处理多个请求,异步非阻塞
- 高峰期表现 进程耗尽,服务崩溃 少量线程即可支撑海量请求
- 资源利用率 低(大量时间处于等待状态) 高(CPU 始终处理有效任务)
核心调度算法
- HAProxy 支持多种调度算法,可根据业务场景灵活选择
- RR(Round Robin,轮询)
- 最常用算法,请求按顺序轮流分配给后端节点
- 适合节点性能相近、无会话状态的场景(如静态页面服务)
- LC(Least Connections,最小连接数)
- 优先将请求转发给当前活跃连接数最少的节点
- 适合节点性能差异大、请求处理时间不一的场景(如动态 API 服务)
- SH(Source Hashing,源地址哈希)
- 根据客户端 IP 计算哈希值,固定转发到同一后端节点
- 适合需要会话保持的场景(如电商购物车、用户登录态)
配置文件:默认没有配置文件需要自行创建:/etc/haproxy/haproxy.cfg
- 全局配置(global)作用:整个 HAProxy 进程的配置
- 进程数、日志、最大连接数、权限、chroot 等,只出现一次,最顶层
- global
- log 127.0.0.1 local2 info # 日志输出到本地 syslog,级别 info
- pidfile /var/run/haproxy.pid # 进程 PID 文件路径
- maxconn 4000 # 单进程最大并发连接数
- user haproxy # 运行用户
- group haproxy # 运行用户组
- daemon # 后台守护进程模式
- # chroot /var/lib/haproxy # 可选,隔离进程目录,增强安全性
- 默认配置(defaults)定义通用参数,被 frontend/backend 继承,简化配置 给下面所有 frontend、backend、listen 统一设置默认值
- 超时时间、重试、模式(http/tcp)、健康检查等写一次,全局生效,不用重复写
- defaults
- mode http # 四层模式改为 tcp
- log global # 继承全局日志配置
- option httplog # 七层记录详细 HTTP 日志,四层改为 tcplog
- option dontlognull # 不记录空连接日志
- option forwardfor # 传递客户端真实 IP 给后端(七层专用)
- option redispatch # 节点故障时强制定向到健康节点
- timeout connect 5000ms # 与后端节点连接超时时间
- timeout client 50000ms # 客户端空闲超时时间
- timeout server 50000ms # 后端节点响应超时时间
- listen配置 内置监控页面,直观查看集群状态,支持账号密码认证 作用:监听端口 + 后端服务器 写在同一段
- 简单、直观、配置少,可以存在多个
- listen stats(listen stats,可选)
- bind *:9000 # 监控页面监听端口
- mode http # 必须为 http 模式
- stats enable # 开启监控
- stats uri /haproxy_stats # 访问路径
- stats auth admin:password123 # 账号密码
- listen web_app
- bind *:80
- server s1 192.168.247.55:8081 check
- server s2 192.168.247.55:8080 check
- 前端配置(frontend)定义 HAProxy 接收请求的方式,包括监听端口、ACL 规则等 作用:接收用户请求,监听端口,做转发规则
- 监听 IP: 端口(bind)根据域名、URL、路径转发到不同 backend
- frontend http_front
- bind *:80 # 监听所有 IP 的 80 端口
- default_backend http_back # 默认转发到 http_back 集群
- # 可选 ACL 规则:按域名分流
- # acl host_www hdr(host) -i www.example.com
- # use_backend www_back if host_www
- 后端配置(backend)定义后端服务器池,包括负载算法、健康检查、节点列表 作用:定义真正的服务器集群
- 写真实的 server IP: 端口 负载均衡算法、健康检查都在这里
- backend http_back
- balance roundrobin # 负载均衡算法
- option httpchk GET /index.html # 七层健康检查:访问指定页面
- # 四层健康检查仅需 check 参数,无需 httpchk
- server web01 192.168.1.11:80 check inter 2000 rise 2 fall 3
- server web02 192.168.1.12:80 check inter 2000 rise 2 fall 3
- # check inter 2000:每 2 秒检查一次
- # rise 2:连续 2 次成功视为节点恢复
- # fall 3:连续 3 次失败视为节点宕机
四层 vs 七层 核心差异
- 对比维度 七层(HTTP 模式) 四层(TCP 模式)
- 数据处理 解析 HTTP 报文,读取 URL/Header/Cookie 不解析报文,仅转发 IP + 端口流量
- 健康检查 option httpchk 检查页面 / 接口状态(如 200 状态码) check 仅检查端口是否存活
- 日志内容 记录请求 URL、状态码、响应字节数,信息详尽 仅记录 IP、端口、连接时长,信息简洁
- ACL 能力 可按域名、URL、请求方法等精细化分流 仅能按源 IP、目标端口分流
- 性能消耗 较高(解包 / 封包消耗 CPU) 极低(直接透传,接近硬件负载均衡)
- 客户端 IP 透传 配置 option forwardfor 即可传递真实 IP 需开启 Proxy Protocol,否则后端看到 HAProxy IP
- 四层模式下刷新页面可能一直命中同一节点,原因是 TCP 长连接复用:
- 浏览器默认开启 HTTP Keep-Alive,建立连接后不会立即断开
- HAProxy 四层模式下,同一 TCP 连接的所有请求会固定转发到同一节点
- 解决方法:关闭后端节点的 Keep-Alive,或改用七层模式
编译安装
- yum install -y gcc gcc-c++ pcre-devel openssl-devel zlib-devel readline-devel #安装依赖
- tar -zxvf lua-5.3.5.tar.gz -C /usr/src #编译安装 Lua
- cd /usr/src/lua-5.3.5
- make linux && make install INSTALL_TOP=/usr/local/lua
- tar -zxvf haproxy-2.2.14.tar.gz -C /usr/src #编译安装 HAProxy
- cd /usr/src/haproxy-2.2.14
- make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_LUA=1 LUA_INC=/usr/local/lua/include/
- make install PREFIX=/usr/local/haproxy
- cp /usr/src/haproxy-2.2.14/examples/haproxy.init /etc/init.d/haproxy #配置系统服务
- chmod +x /etc/init.d/haproxy
- chkconfig --add haproxy
- systemctl start haproxy
- 日志配置
- 修改 HAProxy 配置文件,添加日志配置
- global
- log 127.0.0.1 local3 info
- 修改 Rsyslog 配置(/etc/rsyslog.conf)
- $ModLoad imudp
- $UDPServerRun 514
- local3.* /var/log/haproxy.log # 日志存储路径
- 重启服务生效
- systemctl restart rsyslog && systemctl restart haproxy
与 LVS/HAProxy/Nginx 对比
- 特性 LVS HAProxy Nginx
- 工作层级 四层(内核态) 四层 + 七层(用户态) 四层 + 七层(用户态)
- 性能 极高(接近硬件) 高 中等偏高
- 功能丰富度 低(仅转发) 高(专业负载均衡) 极高(兼顾 Web 服务 / 缓存)
- 健康检查 基础(依赖 Keepalived) 精细(支持 URL / 脚本) 基础(开源版较弱)
- 配置复杂度 高 中等 低
- 适用场景 超大规模流量入口(第一层负载) 复杂业务调度(第二层负载) Web 网关 / 中小型负载
- 三者的层级定位
- LVS → 四层(网络层 / 传输层)
- 工作在 IP + 端口 层
- 只做流量转发,不理解 HTTP
- 性能最强,内核态
- HAProxy → 四层 + 七层
- 既能做四层(TCP),也能做七层(HTTP)
- 专业负载均衡器
- Nginx → 七层为主,四层为辅(stream 模块)
- 主职:Web 服务器、静态资源、缓存
- 兼职:七层反向代理、负载均衡
- 四层功能弱(开源版)
- 能不能互相替换
- LVS ↔ HAProxy
- 四层场景可以互相替换
- 七层场景 LVS 绝对不能替换 HAProxy(LVS 不认识 HTTP)
- HAProxy ↔ Nginx
- 七层 HTTP 负载均衡:可以互相替换
- 四层 TCP 代理:HAProxy 可以替换 Nginx,Nginx 不能很好替换 HAProxy
- 静态资源 / Web 服务:HAProxy 绝对不能替换 Nginx
- LVS ↔ Nginx
- 几乎不能互相替换
- LVS 不做 HTTP,Nginx 四层弱、性能不如 LVS
Mysql主从搭建
MySQL 主从复制
MySQL 主从复制
- 实现数据同步、读写分离、故障备份的核心方案,通过主库写、从库读的架构,可有效分担单台数据库压力,提升系统可用性和扩展性
核心概念与原理
- 读写分离:主库(Master)负责 INSERT/UPDATE/DELETE 等写操作,从库(Slave)负责 SELECT 读操作,避免读写冲突
- 数据备份:从库作为主库的热备,主库故障时可切换到从库,减少数据丢失风险
- 负载均衡:多从库分担读请求压力,支撑更高并发的查询业务
主从复制核心流程
- 主库写 binlog
- 主库开启二进制日志(binlog),所有 DML/DDL 操作都会按顺序记录到 binlog 中,这是主从同步的数据源。
- 从库拉取并写入 relay log
- 从库启动 I/O 线程,连接主库并请求 binlog。
- 主库启动 binlog dump 线程,推送 binlog 数据给从库。
- 从库 I/O 线程将接收的数据写入本地 中继日志(relay log)。
- 从库执行 relay log
- 从库启动 SQL 线程,读取 relay log 中的 SQL 语句并执行,实现数据重放,保证主从数据一致
三种复制模式对比
- SBR(基于语句)
- 核心逻辑:记录执行的 SQL 语句,从库重放
- 优点:日志体积小、节省带宽、易审计
- 缺点:含 NOW()/RAND() 等函数时容易导致数据不一致
- 适用场景:简单业务场景、旧版本 MySQL
- RBR(基于行)
- 核心逻辑:记录数据行的最终变化结果
- 优点:数据一致性高、无函数歧义
- 缺点:日志体积大、网络 IO 压力大
- 适用场景:复杂业务、MySQL 8.0+ 推荐
- MBR(混合模式)
- 核心逻辑:自动判断,普通 SQL 用 SBR,复杂操作切 RBR
- 优点:兼顾效率与安全
- 缺点:逻辑复杂,现代环境逐渐弃用
- 适用场景:过渡场景
- 主流选择:RBR 是当前生产环境首选,数据安全优先级高于带宽消耗
关键特性
- 异步复制(默认):主库执行事务后立即返回,不等待从库同步,存在主从延迟风险。
- 半同步复制:主库需等待至少一个从库写入 relay log 后才返回,降低数据丢失风险,但会牺牲部分性能。
- GTID(全局事务 ID):每个事务分配唯一 ID,替代传统的 binlog 文件名 + 偏移量 方式,简化主从切换和故障恢复
主从复制搭建步骤
- 前置准备
- 主从数据库版本一致,网络互通,关闭防火墙 / SELinux。
- 克隆的从库需删除 /var/lib/mysql/auto.cnf,避免 server_uuid 冲突
- 主库(Master)配置:修改配置文件 /etc/my.cnf
- [mysqld]
- server-id = 1 # 主从 server-id 必须唯一
- log-bin = mysql-bin # 开启 binlog
- sync_binlog = 1 # 事务提交立即刷盘,保证数据安全
- gtid_mode = ON # 开启 GTID
- enforce_gtid_consistency = ON # 强制 GTID 一致性
- binlog_format = ROW # 采用行模式复制
- max_connections = 2000
- innodb_flush_log_at_trx_commit = 1 # 确保 InnoDB 数据安全
- sql_mode = NO_ENGINE_SUBSTITUTION
- systemctl restart mysqld #重启主库
- MySQL -u root -p123.com
- CREATE USER 'replication_user'@'%' IDENTIFIED BY '你的密码'; # 创建复制专用用户
- GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%'; # 授予复制权限
- FLUSH PRIVILEGES; #刷新权限
- SHOW MASTER STATUS; # 查看主库状态(无需记录 File 和 Position,GTID 自动定位)
- 从库(Slave)配置:修改配置文件 /etc/my.cnf
- [mysqld]
- server-id = 2 # 不能与主库重复,多从库依次递增
- relay-log = relay-bin # 开启中继日志
- gtid_mode = ON
- enforce_gtid_consistency = ON
- sql_mode = NO_ENGINE_SUBSTITUTION
- systemctl restart mysqld
- MySQL -u root -p123.com
- CHANGE MASTER TO # 配置主从同步(GTID 自动定位)
- MASTER_HOST='主库IP',
- MASTER_USER='replication_user',
- MASTER_PASSWORD='你的密码',
- MASTER_PORT=3306,
- MASTER_AUTO_POSITION=1;
- START SLAVE #启动主从同步,停止为STOP SLAVE
- SHOW SLAVE STATUS\G # 检查同步状态(核心:两个 Yes)
- 状态校验标准
- Slave_IO_Running: Yes(I/O 线程正常,能拉取 binlog)
- Slave_SQL_Running: Yes(SQL 线程正常,能执行 relay log)
- Seconds_Behind_Master: 0(主从延迟为 0,数据实时同步)
读写分离
- 读写分离是在主从复制基础上,将写请求路由到主库,读请求路由到从库,常见两种实现方式
- 业务代码层实现(成本低、适合中小型项目)
- 核心逻辑:在代码中区分读写操作,写操作连接主库,读操作连接从库
- 优点:配置简单、无需额外中间件
- 缺点:耦合业务代码,扩容从库时需修改代码
- 中间件代理实现(解耦、适合大型集群)
- 通过中间件统一接收数据库请求,自动分发读写操作,主流中间件包括 MyCat、ProxySQL、Atlas 等
- 本质
- 目标:写操作走主库,读操作走从库,分摊数据库压力,提升并发能力
- 依赖基础:必须先搭建好 MySQL 主从复制(主库数据同步到从库)
- 实现方式:通过 MyCat 中间件做 SQL 路由,应用只需要连接 MyCat,无需关心后端主从库
MyCat 核心配置文件
- server.xml 配置 MyCat 登录用户、密码、关联的逻辑库 schemas(必须和 schema.xml 的逻辑库名一致)
- schema.xml 配置逻辑库、数据节点、主从库信息、读写分离策略 balance(读写分离开关)、writeHost(主库)、
- readHost(从库)
读写分离核心参数(schema.xml 中)
- balance 0 所有读写都走主库(不开启读写分离)
- 1 读请求走从库,写请求走主库(生产首选)
- 2 读请求随机分发到主库和从库
- 3 读请求只走从库,主库不承担读压力
- switchType 1 主库宕机自动切换到备用主库
- 2 基于主从同步状态切换(单主单从推荐)
- writeType 0 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个
- 1 所有写操作都随机的发送到配置的 writeHost
- ignoreTxOnSlave true 允许事务内的读请求走从库(需容忍数据延迟)
- 关键注意点
- 事务内的 SELECT 语句,MyCat 会默认走主库(保证数据一致性)
- server.xml 的 schemas 必须和 schema.xml 的逻辑库名完全一致,否则 MyCat 启动失败
- 防火墙必须开放 MyCat 的 8066/9066 端口、MySQL 的 3306 端口
- 8066:数据访问端口,用于业务 SQL 执行、读写分离路由应用程序 对象业务开发
- 9066:管理控制台端口,用于服务监控、配置重载、状态查询 对象运维人员
前提环境(已完成的主从复制检查)
- 登录主库(192.168.247.55),检查主库状态
- mysql -uroot -p123.com -h192.168.247.55 -P3306 # 执行命令,查看 binlog 是否开启
- SHOW MASTER STATUS;
- 输出有 File 和 Position 字段,说明主库配置正常
- 登录从库(192.168.247.56),检查同步状态
- mysql -uroot -p123.com -h192.168.247.56 -P3306 # 执行命令,核心看两个参数
- SHOW SLAVE STATUS\G
- 必须满足:Slave_IO_Running=Yes 且 Slave_SQL_Running=Yes,说明主从同步正常
MyCat 读写分离 分步操作
- 准备 MyCat 运行环境(JDK 8)
- java -version
- 关闭防火墙
- systemctl stop firewalld
- Mysql
- CREATE USER 'admin'@'%' IDENTIFIED BY '123.com'; #创建一个给 Mycat 用的账号
- GRANT ALL PRIVILEGES ON wordpress.* TO 'admin'@'%';
- FLUSH PRIVILEGES;
- MyCat
- tar -zxvf Mycat-server-1.6.7.3-release-20190927161129-linux.tar.gz
- cd /root/mycat
- 修改 server.xml(谁能访问 MyCat + 访问权限)
- cp /root/mycat/conf/server.xml /root/mycat/conf/server.xml.bak #备份
- 写入新配置(直接覆盖)
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE mycat:server SYSTEM "server.dtd">
- <mycat:server xmlns:mycat="http://io.mycat/">
- <!-- 管理员用户:可读写 -->
- <user name="admin" defaultAccount="true">(当登录时没有指定用户,默认为admin)
- <property name="password">123.com</property>
- <property name="schemas">wordpress_logic</property>
- </user>
- <!-- 可选:只读用户,提升安全性 -->
- <user name="read_user">
- <property name="password">123.com</property>
- <property name="schemas">wordpress_logic</property>
- <property name="readOnly">true</property>
- </user>
- </mycat:server>
- 修改 schema.xml(SQL 怎么路由 + 读写分离规则)
- cp /root/mycat/conf/schema.xml /root/mycat/conf/schema.xml.bak #备份
- 写入新配置(适配你的主从库 IP)
- <?xml version="1.0"?>
- <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
- <mycat:schema xmlns:mycat="http://io.mycat/">
- <!-- 逻辑库:wordpress_logic,和 server.xml 一致 -->
- <schema name="wordpress_logic" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"/>
- <!-- 数据节点:关联逻辑库和主从库 -->
- <dataNode name="dn1" dataHost="host1" database="wordpress"/>
- <!-- 数据主机:配置主从库信息+读写分离核心 -->
- <dataHost name="host1" maxCon="1000" minCon="10" balance="1"
- writeType="0" dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
- <!-- 心跳检测 SQL:确保 MyCat 能连通主从库 -->
- <heartbeat>select user()</heartbeat>
- <!-- 主库配置 -->
- <writeHost host="master1" url="192.168.247.55:3306" user="root" password="123.com">
- <!-- 从库配置:嵌套在 writeHost 里 -->
- <readHost host="slave1" url="192.168.247.56:3306" user="root" password="123.com"></readHost>
- </writeHost>
- </dataHost>
- </mycat:schema>
- 检查 XML 语法(避免启动失败)
- yum install -y libxml2
- xmllint --noout /root/mycat/conf/server.xml # 检查 server.xml
- xmllint --noout /root/mycat/conf/schema.xml # 检查 schema.xml
- 无任何输出 → 语法正确;
- 有报错 → 根据提示修改
- 启动 MyCat 并验证启动状态
- cd /root/mycat/bin
- ./mycat start #启动mycat
- tail -f /root/mycat/logs/wrapper.log #查看日志,查看是否成功启动
- 启动成功标志:日志中出现 MyCAT Server startup successfully. see logs in logs/mycat.log
- 验证读写分离功能
- mysql -uadmin -p123.com -h192.168.247.57 -P9066 #连接 MyCat 9066 管理端口
- show @@datanode; # 执行命令,查看数据节点状态
- show @@datasource; #查看连接状态
- mysql -uadmin -p123.com -h192.168.247.57 -P8066 #连接 MyCat 数据端口
- 查看日志
- SET GLOBAL general_log = 'ON';#观察读写分离日志(mysql)
- tail -f /data/mysql/localhost.log(shell命令行)
- # 路径可能因安装方式而异,可以通过 show variables like 'general_log_file' 查看
常见问题排查手册
- 问题现象
- 启动报错 schema TESTDB refered by user root is not exist
- server.xml 和 schema.xml 的逻辑库名不一致
- 统一改为 wordpress_logic
- 连接 MyCat 报 ERROR 2003 (HY000): Can't connect to MySQL server
- 防火墙未关 / 端口未开放,或 MyCat 未启动
- 关闭防火墙,重启 MyCat
- 读操作不走从库
- 1. balance 配置不是 1;2. SQL 在事务内
- 1. 改为 balance="1";2. 用 SQL Hint 强制路由
- 主从数据不一致
- 主从复制异常
- 登录从库执行 SHOW SLAVE STATUS\G,确保两个 Yes
Mongodb(非关系型数据库)
核心定位
核心定位
- 文档型非关系数据库(NoSQL),schema-less 设计,无需预定义数据结构,适配不规则 / 多变数据场景
- 核心优势:存储灵活、读写性能优异、原生支持分片集群,适合海量数据存储
- 适用于存储结构、半结构化数据
数据格式:BSON
- 定义:二进制 JSON(Binary JSON),MongoDB 默认存储和数据交换格式
- 优势:支持日期、二进制数据等 JSON 不具备的类型;解析效率高、可遍历性强;兼容嵌套文档和数组结构
JSON和BSON
- JSON是当今非常通用的一种跨语言Web数据交互格式,SpringBoot都选择了JSON作为默认的数据编/解码格式
- 类似键值对 name(键):张山(值)
- BSON(Binary JSON)是二进制版本的JSON,,其在性能方面有更优的表现
- 二者最大的区别在于JSON是基于文本的,而BSON则是二进制(字节流)编/解码的形式
与关系型数据库对比
- SQL 概念 MongoDB 概念 说明
- 数据库(database) 数据库(database) 数据存储容器
- 表(table) 集合(collection) 文档的集合,类似表结构
- 行(row) 文档(document) 最小数据单元,BSON 格式
- 列(column) 字段(field) 文档中的键值对
- 主键(primary key) _id 字段 自动生成,默认 ObjectId 类型
- 表连接(join) 聚合操作 $lookup 无原生表连接,需通过 $lookup 模拟
核心数据库
- admin 超级管理员控制台 权限管理、执行全局命令(如关闭服务)
- local 本地缓存 存储节点私有数据,不参与集群同步
- config 集群元数据 分片集群的 “大脑”,存储分片配置
关键操作命令
- 数据库与集合操作
- 切换 / 创建数据库:use dbname(延迟创建,写入数据后实际生成)
- 查看非空数据库:show dbs;查看当前数据库:db
- 查看集合:show collections
- 删除当前数据库:db.dropDatabase();删除集合:db.<collection>.drop()
- 数据增删改查
- 新增(Insert)
- 单条插入:db.collection.insertOne({字段: 值})
- 多条插入:db.collection.insertMany([{...}, {...}])
- 支持嵌套文档和数组字段插入(如 area: {province: "beijing"}、color: ["black", "white"])
- 查询(Find)
- 查询所有:db.collection.find()(格式化显示:find().pretty())
- 字段投影:db.collection.find({}, {字段1:1, 字段2:1, _id:0})(1 = 显示,0 = 隐藏)
- 排序与分页:sort({字段:1/-1})(1 升序,-1 降序)、skip(跳过条数).limit(返回条数)
- db.users.find().sort({ age: 1 })
- db.users.find().skip(10).limit(5)
- 条件查询:
- 等于:db.users.find({ name: "Alice" })
- 大于 ($gt):db.users.find({ age: { $gt: 20 } })
- 逻辑或 ($or):db.users.find({ $or: [{ name: "Alice" }, { age: 30 }] })
- db.goods.find({price:{'$lte':1999},number:{'$gte':40}})
- 操作符: $gt 大于 $gte 大于等于
- $lt 小于 $lte 小于等于
- 更新(Update)
- 核心要求:必须使用 $set 关键字,避免替换整个文档
- 单条更新:db.collection.updateOne({查询条件}, {$set: {更新字段}})
- 多条更新:db.collection.updateMany({查询条件}, {$set: {更新字段}})
- 删除字段:db.collection.updateOne({条件}, {$unset: {字段: 0}})
- 删除(Delete)
- 单条删除:db.collection.deleteOne({查询条件})
- 多条删除:db.collection.deleteMany({查询条件})(慎用)
- 清空集合:db.collection.deleteMany({})(保留集合结构)
- 删除整个集合(表):db.users.drop()
- 运维铁律:先执行 find 验证条件,再执行 delete,条件必须一致
核心启动参数
- --dbpath 指定数据存储目录(必填)
- --logpath 指定日志文件路径
- --port 监听端口(默认 27017)
- --fork 后台启动服务
- --auth 开启权限认证
- --bind_ip 绑定允许访问的 IP
适用场景与禁用场景
- 适用场景
- 数据结构经常变化(如用户资料、商品属性)
- 天然 JSON 结构数据(评论系统、订单数据、IoT 设备数据)
- 读多写少、以查询为主的系统(内容平台、商品展示系统)
- 日志 / 监控 / 埋点数据(写入量大、结构多变、很少更新)
- 快速迭代项目、需要水平扩展的海量数据场景
- 禁用场景
- 强事务需求(如银行系统、财务系统)
- 高一致性要求场景(如库存扣减)
- 复杂报表系统、高频复杂联表更新场景
- 强关联数据场景(关系型数据库更适配)
注意点
- 延迟创建:use dbname 仅逻辑切换,需写入数据才实际创建数据库
- 更新必加 $set:未使用 $set 会替换整个文档,导致字段丢失
- 多维字段查询:需用引号包裹完整路径(如 "area.city")
- 权限认证:超级管理员需在 admin 库创建和认证,普通用户仅能访问授权数据库
- 投影查询:除 _id 外,字段显示(1)和隐藏(0)不能混合使用
Redis
核心定位与特性
核心定位与特性
- 远程字典服务(Remote Dictionary Server),基于内存的高性能 Key-Value 缓存数据库,支持持久化,是一种缓存的中间件(默认端口6379)
- 开发语言:C 语言;默认端口:6379;支持 16 个数据库(0-15),默认使用数据库 0
- 核心优势:支持五大核心数据结构(String、List、Set、ZSet、Hash )、读写性能优异、支持主从复制与高可用、可持久化(数据不丢失)
- 与 Memcached 对比:支持更丰富的数据结构(List/Set/Hash 等)、支持持久化和主从模式、单个 Value 最大 512MB(Memcached 仅 1MB)
本质
- Redis 本质是「内存级数据处理引擎」—— 既解决了数据库高并发瓶颈,又通过灵活的数据结构适配多种业务场景
- 同时为分布式架构提供锁、会话、限流等核心支撑,是现代互联网系统不可或缺的中间件
核心作用
- 高性能缓存 + 多场景数据存储 + 分布式架构支撑
- 热点数据缓存(核心作用)
- 把数据库中高频访问的数据(如商品详情、用户信息、首页推荐)缓存到 Redis 内存中,
- 请求直接从 Redis 读取,避免频繁查询数据库
- 降低数据库压力,响应速度从毫秒级(数据库)提升到微秒级(内存),支撑高并发访问(如电商大促、秒杀场景)
- 数据结构存储(灵活适配业务)
- 利用 String/List/Set/ZSet/Hash 五大核心数据结构,直接存储业务数据,无需依赖数据库
- 分布式架构支撑
- 基于 String 类型的 SET NX 命令,解决多服务并发竞争资源问题
- 存储用户登录会话(Token),实现多台应用服务器间的会话同步
- 基于 ZSet 或计数器实现接口限流(如限制单 IP 每秒请求次数),配合缓存雪崩 / 击穿解决方案,保障分布式架构稳定
- 数据持久化与高可用
- 支持 RDB/AOF 持久化,把内存数据落地到磁盘,避免服务重启数据丢失
- 结合主从复制、哨兵模式、集群模式,实现数据备份、读写分离、故障自动切换,保障服务高可用(无单点故障)
- 缓解数据库压力(架构优化)
- 分担数据库读请求:主从复制中,Redis 从节点承接读流量,主节点专注写操作
- 替代数据库存储临时数据:如验证码(设置过期时间自动失效)、临时会话、接口请求缓存,减少数据库无效读写
通用 Key 操作(在redis客户端界面输入{./redis-cli})
- KEYS pattern 匹配符合规则的 Key 支持 *(任意字符)、?(单个字符)、[](指定字符)通配符
- EXISTS key 判断 Key 是否存在 存在返回 1,不存在返回 0
- DEL key 删除 Key 返回被删除 Key 的个数
- EXPIRE key s 设置 Key 过期时间(单位:秒) 覆盖已有过期时间,返回 1 表示成功,0 表示 Key 不存在
- TTL key 查看 Key 剩余过期时间 -1 表示永久有效,-2 表示已过期
- SELECT num 切换数据库 数据库编号 0-15,默认使用数据库 0,num为0-15的一个变量
- DBSIZE 统计当前数据库 Key 总数 -
- FLUSHDB 清空当前数据库所有 Key -
- FLUSHALL 清空所有数据库 Key(生产环境慎用) -
- PING 测试客户端与服务器连接 返回 PONG 表示连接正常
五大核心数据结构操作
- String
- 核心命令:SET/GET、INCR/DECR、MSET/MGET、APPEND
- 用于计数器、简单缓存、字符串存储
- 特性:单个 Value 最大 512MB,支持自增自减
- 命令 作用 实操示例(可直接执行)
- SET key value 设置键值对 SET username zhangsan(设置 username=zhangsan)
- GET key 获取值 GET username(返回 "zhangsan")
- INCR key 数值 + 1(计数器) SET view_count 100 → INCR view_count(返回 101)
- DECR key 数值 - 1 DECR view_count(返回 100)
- INCRBY key num 数值 + 指定数 INCRBY view_count 10(返回 110)
- MSET k1 v1 k2 v2 批量设置 MSET age 20 gender male(同时设 age=20、gender=male)
- MGET k1 k2 批量获取 MGET age gender(返回 ["20","male"])
- APPEND key str 追加字符串 APPEND username _vip → GET username(返回 "zhangsan_vip")
- SETEX key s value 设置键值 + 过期时间(秒) SETEX code 120 6666(验证码 6666,2 分钟过期)
- SETNX key value 不存在则设置(分布式锁) SETNX lock_order 1(成功返回 1,已存在返回 0)
- List
- 核心命令:LPUSH/RPUSH、LPOP/RPOP、LRANGE、LLEN
- 用于消息队列、最新数据排行
- 特性:双向链表,支持栈(先进后出)/ 队列(先进先出)
- 命令 作用 实操示例(可直接执行)
- LPUSH key val 左侧(头部)添加元素 LPUSH news "redis教程" → LPUSH news "mysql教程"
- RPUSH key val 右侧(尾部)添加元素 RPUSH news "linux教程"
- LPOP key 左侧弹出元素 LPOP news(返回 "mysql 教程")
- RPOP key 右侧弹出元素 RPOP news(返回 "linux 教程")
- LRANGE key start end 查看区间元素 LRANGE news 0 -1(查看所有元素,返回 ["redis 教程"])
- LLEN key 查看列表长度 LLEN news(返回 1)
- LTRIM key start end 截取列表(保留指定区间) LTRIM news 0 0(仅保留第一个元素)
- Set
- 核心命令:SADD/SREM、SINTER(交集)、SUNION(并集)、SISMEMBER
- 用于共同好友、黑白名单、去重
- 特性:无序无重复元素,支持集合运算
- 命令 作用 实操示例(可直接执行)
- SADD key val 添加元素(自动去重) SADD user_1_friends 1001 1002 1003
- SADD key val 再添加重复元素(无效果) SADD user_1_friends 1002 → SMEMBERS user_1_friends(仍为 1001/1002/1003)
- SMEMBERS key 查看所有元素 SMEMBERS user_1_friends(返回 ["1001","1002","1003"])
- SREM key val 删除指定元素 SREM user_1_friends 1003(返回 1,删除成功)
- SISMEMBER key val 判断元素是否在集合中 SISMEMBER user_1_friends 1001(返回 1,存在)
- SINTER k1 k2 求交集(共同好友) SADD user_2_friends 1001 1004 → SINTER user_1_friends user_2_friends(返回 ["1001"])
- SUNION k1 k2 求并集 SUNION user_1_friends user_2_friends(返回 ["1001","1002","1004"])
- SDIFF k1 k2 求差集(k1 有 k2 无) SDIFF user_1_friends user_2_friends(返回 ["1002"])
- ZSet
- 核心命令:ZADD、ZRANGE/ZREVRANGE、ZINCRBY、ZSCORE
- 用于排行榜(Top N)、权重排序
- 特性:有序集合,元素唯一,关联 Score 权重值
- 命令 作用 实操示例(可直接执行)
- ZADD key score val 添加元素 + 权重(score) ZADD hot_video 98 "视频A" → ZADD hot_video 95 "视频B" 99 "视频C"
- ZRANGE key start end 升序查看区间元素 ZRANGE hot_video 0 -1(返回 ["视频 B","视频 A","视频 C"])
- ZREVRANGE key start end 降序查看区间元素 ZREVRANGE hot_video 0 1(返回 ["视频 C","视频 A"],取 TOP2)
- ZINCRBY key num val 增加元素权重 ZINCRBY hot_video 2 "视频B" → ZSCORE hot_video "视频B"(返回 97)
- ZSCORE key val 查看元素权重 ZSCORE hot_video "视频C"(返回 99)
- ZREM key val 删除指定元素 ZREM hot_video "视频A"(返回 1,删除成功)
- Hash
- 核心命令:HMSET/HGET、HGETALL、HDEL、HMGET
- 用于存储对象(用户信息、商品属性)
- 特性:字段 - 值映射,压缩效率高,适合结构化数据
- 命令 作用 实操示例(可直接执行)
- HMSET key f1 v1 f2 v2 批量设置字段值 HMSET user_1001 name lisi age 25 city beijing
- HGET key field 获取单个字段值 HGET user_1001 age(返回 "25")
- HMGET key f1 f2 批量获取字段值 HMGET user_1001 name city(返回 ["lisi","beijing"])
- HGETALL key 获取所有字段 + 值 HGETALL user_1001(返回 ["name","lisi","age","25","city","beijing"])
- HDEL key field 删除指定字段 HDEL user_1001 city(返回 1,删除成功)
- HEXISTS key field 判断字段是否存在 HEXISTS user_1001 city(返回 0,已删除)
- HINCRBY key field num 字段数值 + 指定数 HINCRBY user_1001 age 1 → HGET user_1001 age(返回 26)
- 总结
- String 核心是「单值存储 + 计数」,适配简单缓存 / 锁场景;
- List/Set/ZSet 适配有序 / 无序 / 权重排序的集合场景;
- Hash 专为「对象存储」设计,避免 String 存储 JSON 的解析开销;
- 所有命令执行前,先通过 SELECT 0 切换到默认数据库,避免操作错误
持久化机制(数据不丢失核心)
- Redis 提供两种持久化方式,可单独或同时启用,平衡性能与数据安全性,分别是RDB和AOF
- RDB
- 原理:在指定时间间隔内,满足指定写操作次数时,生成二进制快照文件(dump.rdb),重启时快速加载恢复、
- 核心配置(redis.conf)
- save 900 1 # 900秒内至少1次写操作触发
- save 300 10 # 300秒内至少10次写操作触发
- save 60 10000 # 60秒内至少10000次写操作触发
- dbfilename dump.rdb # 快照文件名
- dir /var/lib/redis # 存储路径
- 优点:文件体积小、备份恢复高效、适合全量备份;缺点:崩溃可能丢失最后一次快照后的数据,大数据集快照生成影响性能
- AOF
- 原理:记录每一次写操作(SET/DEL/INCR 等),追加到日志文件(appendonly.aof),重启时重放日志恢复数据
- 核心配置(redis.conf)
- appendonly yes # 启用 AOF
- appendfilename "appendonly.aof" # 日志文件名
- appendfsync everysec # 同步频率(每秒同步,折中选择)
- auto-aof-rewrite-percentage 100 # 日志文件达到原大小2倍时自动重写
- auto-aof-rewrite-min-size 64mb # 重写最小文件大小
- 优点:数据安全性高(丢失风险低)、支持日志修复(redis-check-aof 工具);缺点:文件体积大,高频写操作时性能略受影响
- 持久化选择策略
- 单独 RDB:追求性能,可接受少量数据丢失(如非核心缓存场景)
- 单独 AOF:追求数据安全,可接受略低性能(如核心业务数据存储)
- 同时启用:性能与安全平衡(重启时优先加载 AOF 文件,数据更完整)
Redis 高可用架构
- 主从复制(主写从读)
- 核心架构:主节点(Master)提供写操作,从节点(Slave/Replica)为只读副本,分担读请求,支持故障转移
- 工作流程
- 建立连接:从节点执行 replicaof <master_ip> <master_port>(旧版本 slaveof),与主节点建立 TCP 连接
- replicaof 192.168.247.55 6379
- 全量同步(初次同步):主节点执行 BGSAVE 生成 RDB 快照,发送给从节点,同时记录生成快照期间的写操作到
- 复制缓冲区,后续同步给从节点
- 增量同步:正常运行时,主节点异步同步写命令到从节点,保持数据一致
- 断线重连:从节点重连后,若复制偏移量在主节点缓冲区范围内则增量同步,否则全量同步
- 配置要点:主节点默认无需特殊配置,从节点配置文件需添加 replicaof 指令,主节点设密码时需配置 masterauth <password>
- 哨兵模式(Sentinel)
- 核心作用:独立进程,监控主从节点状态,主节点故障时自动选举新主节点,通知客户端和从节点切换,实现高可用
- 核心功能:监控(检测主从节点存活)、自动故障转移、通知客户端、提供配置查询
- 部署要求:至少 3 个哨兵节点(奇数个,避免选举平票),通过 Raft 协议达成决策一致
- 核心配置(sentinel.conf)
- port 26379 # 哨兵端口
- sentinel monitor mymaster 192.168.1.10 6379 2 # 2个哨兵同意即判定主节点宕机
- sentinel down-after-milliseconds mymaster 5000 # 5秒无响应标记为主观下线
- 适用场景:中小型集群(数据量 < 50GB,QPS < 10 万),运维成本低,上手快
- 集群模式(Redis Cluster)
- 核心目标:数据分片(突破单机内存限制)+ 高可用 + 去中心化,适用于大数据量(>100GB)、高 QPS(>50 万)场景
- 核心原理
- 数据分片:通过 16384 个哈希槽(Slot)分配数据,主节点至少 3 个,
- 每个主节点负责部分槽(如 Master1:0-5460,Master2:5461-10922,Master3:10923-16383);
- 节点通信:节点间通过 Gossip 协议同步状态,无中心节点;
- 请求路由:客户端请求打到非目标槽节点时,返回 MOVED 重定向指令,客户端自动重试
- 部署要求:最小规模 6 个节点(3 主 3 从),主从节点需分布在不同物理机,避免单点故障
- 核心命令
- 创建集群:redis-cli --cluster create 节点IP:端口... --cluster-replicas 1(1 主 1 从)
- 查看集群状态:CLUSTER NODES、CLUSTER INFO
- 修复集群:redis-cli --cluster fix 节点IP:端口
- 架构对比(哨兵 vs 集群)
- 对比维度 哨兵模式 集群模式
- 数据分布 全量复制 分片存储(16384 槽)
- 故障切换 哨兵自动选主 集群节点投票选主
- 扩容方式 垂直扩容为主 水平扩容(新增节点 + 重新分片)
- 适用场景 中小型集群(数据量 <50GB) 大型分布式集群(数据量 >100GB)
- 运维复杂度 低 高
缓存常见问题与解决方案
- 缓存雪崩
- 定义:大量缓存同一时间失效,请求集中穿透到数据库,导致数据库压力骤增甚至宕机
- 解决方案
- 过期时间加随机值(如 10min±5min),避免同时失效
- 多级缓存(本地缓存 + Redis),避免 Redis 挂掉直接打数据库
- 热点数据预加载(启动时加载核心数据到缓存)
- 限流降级(Redis 故障时,限制请求流量,返回兜底数据)
- 缓存击穿
- 定义:单个热点 Key 过期,大量并发请求穿透到数据库
- 解决方案
- 互斥锁(分布式锁):第一个请求抢锁查询数据库并写回缓存,其他请求等待锁释放后读缓存
- 逻辑过期:Key 不设物理过期时间,内置过期字段,后台线程异步刷新
- 热点数据永不过期:通过定时任务主动更新缓存,避免过期
- 缓存穿透
- 定义:请求查询一个根本不存在的数据,缓存和数据库都没有这条数据,导致请求每次都穿透到数据库
- 解决方案:
- 缓存空值:数据库查询无结果时,将空值缓存并设置短过期时间,拦截后续相同无效请求
- 布隆过滤器:前置校验层存储所有有效 Key,直接拦截不存在的 Key 请求
- 前置参数校验:接口层过滤非法、无效请求参数,拦截明显的无效查询
- 限流熔断兜底:通过限流组件控制接口请求频率,避免数据库被无效请求压垮
- 其他核心问题
- 脑裂问题:哨兵模式配置合理 quorum 值,集群模式设置 cluster-require-full-coverage no
- 数据丢失:主从复制开启 min-slaves-to-write 1(至少 1 个从节点同步成功才允许写)、min-slaves-max-lag 10(同步延迟不超过 10 秒)
- 跨槽操作失败:集群模式下多 Key 操作需确保在同一槽,可通过 Hash Tag(如 {user:1000}:profile)实现
分布式架构中的 Redis 定位
- 架构演进角色:随着业务访问量增长,Redis 作为缓存层逐步融入架构,典型演进路径:
- 单应用架构 → 应用 - 数据库分离 → 应用集群 → 数据库读写分离 → 引入 Redis 缓存 → 数据库拆分 → 微服务架构
- 核心作用:缓存热点数据(减少数据库查询压力)、存储非结构化 / 高频访问数据(如用户会话、排行榜、计数器),
- 与搜索引擎、数据库配合提升系统整体性能
核心运维要点
- 安装与启动
- yum -y install gcc*
- tar -zxvf 安装包
- cd redis
- make PREFIX=/usr/local/redis install
- 后台启动:修改配置文件 daemonize yes,进入/redis/bin下执行 redis-server /usr/local/redis/redis.conf
- 安全设置:配置密码(requirepass 密码),限制访问 IP(bind 信任IP),关闭保护模式(protected-mode no)
- 通常保护模式是开启的 保护模式开启时,开启后,Redis 只会绑定127.0.0.1,非本地 IP 的客户端无法连接 Redis,
- 导致业务服务无法访问 Redis,进而出现缓存读取 / 写入失败、业务报错
- bind 默认是127.0.0.1,配置IP可以在这里设置,若想要所有IP都可以访问则写为0.0.0.0
- 关键配置汇总
- 配置项 作用 推荐值
- daemonize 后台启动 yes
- bind 绑定访问 IP 信任的服务器 IP
- requirepass 登录密码 复杂密码(生产环境必填)
- appendonly 启用 AOF 持久化 yes
- appendfsync AOF 同步频率 everysec
- cluster-enabled 启用集群模式 yes(集群部署)
- cluster-node-timeout 集群节点超时时间 5000ms
- 常用运维命令
- 连接客户端:redis-cli -h IP -p 端口 -a 密码
- 查看服务器信息:INFO(如 INFO replication 查看主从状态)
- 手动备份 RDB:SAVE(阻塞)、BGSAVE(非阻塞)
- 修复 AOF 日志:redis-check-aof --fix appendonly.aof
中间件对比
简单说,中间件是独立的系统软件,它不直接给用户提供业务功能,而是帮应用程序解决通信、数据存储、性能优化等通用问题,
简单说,中间件是独立的系统软件,它不直接给用户提供业务功能,而是帮应用程序解决通信、数据存储、性能优化等通用问题,
- 让开发人员可以专注于业务逻辑
Redis(缓存中间件)
- 核心定位 高性能内存 Key-Value 缓存,支持持久化
- 核心作用 缓存热点数据,降低数据库压力 实现计数器、排行榜、 分布式锁 支撑分布式架构高可用
- 数据存储格式 支持 String、List、Set、ZSet、Hash 五大数据结构
- 核心协议 / 默认端口 Redis 自研协议 6379
- 高可用方案
- 主从复制:主写从读
- 哨兵模式:自动故障转移
- 集群模式:数据分片 + 去中心化
- 适用场景
- 热点数据缓存(商品详情、首页推荐)
- 计数器、排行榜、分布式锁
- 限流、会话共享
- 不适用场景
- 大量冷数据存储(内存成本高)
- 强事务、强一致性需求(如金融交易)
- 核心特性
- 高性能:单机 QPS 可达 10 万 +
- 持久化:RDB 快照、AOF 日志
- 支持 Key 过期自动删除
- 关键运维命令
- 数据操作:SET/GET LPUSH/LPOP
- 主从配置:replicaof
- 集群管理:CLUSTER NODES
MyCat(数据库中间件)
- 核心定位 分布式数据库中间件,专注 MySQL 读写分离与分库分表
- 核心作用 读写分离:写走主库,读走从库 分库分表:拆分大表,突破单机瓶颈 统一数据访问入口,应用无需感知底层数据库
- 数据存储格式 基于关系型数据库表结构,与 MySQL 完全兼容
- 核心协议 / 默认端口 模拟 MySQL 协议 8066(业务访问(增、删、改))、9066(管理)
- 高可用方案
- 依赖 MySQL 主从复制
- 单表千万级以上数据分库分表
- 分布式系统统一数据访问层
- 适用场景
- MySQL 读写分离架构
- 小数据量、低并发场景(没必要引入)
- 不适用场景
- 非 MySQL 生态数据库
- 小数据量、低并发场景(没必要引入)
- 核心特性
- 兼容 SQL 语法,应用无感知迁移
- 读写分离策略可配置(balance 参数)
- 支持全局表、ER 表等拆分规则
- 关键运维命令
- 业务访问:mysql -h IP -P 8066 -u 用户名 -p
- 管理命令:show @@datanode(查看从信息) show @@datasource(查看架构信息)
- 重载配置:reload @@config
Nginx(反向代理 / 负载均衡中间件)
- 核心定位 反向代理、负载均衡、静态资源服务器(web容器)
- 核心作用 负载均衡:分发请求到多台应用服务器 反向代理:隐藏后端 IP,提升安全性 动静分离:缓存静态资源(图片 / JS/CSS)SSL 证书配置,实现 HTTPS
- 数据存储格式 不存储业务数据,仅转发请求或缓存静态资源
- 核心协议 / 默认端口 HTTP/HTTPS/TCP 协议 、80(HTTP)、443(HTTPS)
- 高可用方案
- 主备模式:一台主节点 + 多台备节点
- 集群模式(Nginx+Keepalived):避免单点故障
- 适用场景
- 应用集群负载均衡(多 Tomcat/Java 服务)
- 动静分离架构
- 反向代理隐藏后端服务
- 高并发 Web 服务入口
- 不适用场景
- 处理复杂业务逻辑
- 存储业务数据
- 替代应用服务器(如 Tomcat)
- 核心特性
- 轻量级、高性能,并发能力强
- 配置简单,支持多种负载均衡算法
- 模块化设计,可扩展第三方模块
- 关键运维命令
- 启动 / 重启:nginx 、nginx -s reload
- 配置检查:nginx -t
- 查看进程:ps -ef
- Redis:聚焦高性能缓存,解决数据库高并发瓶颈,是分布式架构的 “性能加速器”
- MyCat:聚焦MySQL 分布式扩展,解决分库分表、读写分离问题,是关系型数据库的 “扩容神器”
- Nginx:聚焦流量入口层,负责请求转发、负载均衡,是分布式架构的 “第一道关卡”
Python
输入与输出
输入与输出
- 输入:input () 函数
- 是 Python 获取用户输入的标准函数,默认返回字符串类型(str),例:name=input("请输入名字")
- 若要处理数字,需显式类型转换,例:age = int(input("请输入年龄:"))
- 输出:print () 函数
- 基本用法:直接打印内容,例:print("Hello World!")
- 多参数输出:默认以空格分隔多个变量 / 内容,以逗号间隔需要输出的东西 例:print("姓名:", name, "年龄:", age)
- 格式化输出(重点,推荐 f-string)
- 适用 Python3.6+,简洁且性能好,左引号前加 f,变量放 {} 内
- 支持变量运算:print(f"明年{age+1}岁")
- 支持数字格式化:print(f"价格:{price:.2f}")(保留 2 位小数,自动四舍五入)
- 文件输入输出(基础)
- 打开文件:open () 函数
- 语法:f = open(filename(文件名), mode(模式), encoding="utf-8"),编码一般指定 utf-8
- 核心模式:r(只读,默认)、w(只写,覆盖 / 新建)、a(追加,末尾写入),可与 b(二进制)组合(如 rb、wb)
- 读写操作
- 写入:f.write("内容");读取:f.read()(全读)、f.readlines()(按行读成列表)、逐行循环读
- 关键:文件使用后需用f.close()关闭,避免资源泄漏;推荐 with 语句,自动关闭文件
- 大文件禁止用f.read()一次性读取,易造成内存溢出
- with open("test.txt", "r", encoding="utf-8") as f:
- data = f.read()
- 写入文件
- f=open("test.txt","a") #打开文件
- f.write("hello") #向文件写入hello,因为是a所以是以追加的方式写入
- f.close() #使用完文件要及时关闭,否则可能造成资源泄漏
- 读取文件
- f=open("test.txt","r")
- print(f.read()) # 1. 一次性读取全部内容
- lines = f.readlines() # 2. 按行读取,返回列表
- print(lines)
- for line in f: # 3. 一行一行读取
- print(line.strip()) # 去掉换行符
- f.close() #使用完文件要及时关闭,否则可能造成资源泄漏
Python 变量
- 六大标准数据类型
- 分类 类型 特性
- 不可变数据 数字(Number)、字符串(String)、元组(Tuple) 值不可修改
- 可变数据 列表(List)、字典(Dictionary)、集合(Set) 值可修改
- 数字类型细分
- 包含 4 类:int(整数)、bool(布尔,True/False)、float(浮点数)、complex(复数,a+bj)
- 浮点数运算规则:只要有一个操作数是浮点数,结果必为浮点数
- 变量定义与赋值
- Python无需声明变量,赋值后才创建,变量无类型,类型是其指向内存对象的类型。
- 多变量赋值:支持a = b = c = 1(同值)或a, b, c = 1, 2, "john"(多值)
- 数据类型转换
- 隐式转换
- Python 自动完成,低精度类型转高精度(如整数→浮点数),避免数据丢失
- 显式转换
- 手动使用内置函数,核心:int()、float()、str(),例:num_str = int("456")
- 常量
- Python无内置常量类型,约定全大写字母表示常量,值应保持不变,例:MAX_CONNECTIONS = 5000
Python 运算符和表达式
- 赋值运算符(核心)
- 基础:=(直接赋值);复合:+=、-=、*=、/=、%=(取模赋值),例:c += a 等效于 c = c + a
- 重要:Python无 i++/i-- 自增自减运算符,用i += 1/i -= 1替代
- 逻辑运算符(3 个)
- 运算符 表达式 描述 实例(a=10, b=20)
- and x and y 与:x 假返 x,x 真返 y a and b → 20
- or x or y 或:x 真返 x,x 假返 y a or b → 10
- not not x 非:取反布尔值 not(a and b) → False
Python 判断语句
- if...elif...else(核心)
- 语法:无括号,条件后加冒号:,用缩进行划分语句块(Python 特色)
- 关键字:if → elif → else,无 else if
- 逻辑:满足前一个条件则执行对应语句块,后续条件不再判断
- if 嵌套
- 可将 if...elif...else 结构放入另一个 if 结构中,缩进层级区分嵌套关系
- match...case(Python3.10 + 新增)
- 替代多分支 if-else,实现模式匹配,语法:match 匹配对象: case 模式1: 操作1
- 通配符:case _: 等效于 Java/C 的 default,匹配所有未命中的情况
Vibe Coding 编程思维
- 维度 传统编程 Vibe Coding
- 核心能力 写代码、背语法 表达需求、说人话
- 学习重点 语言、算法、数据结构 产品思维、需求表达、迭代
- 工作方式 从零手写代码 和 AI 对话生成代码
- 调试 / 优化 自主调试、重构 告诉 AI 错误 / 优化方向
- 学习曲线 陡峭(数月到数年) 平缓(几天上手)
- 适合人群 理工科、逻辑思维强 所有会表达需求的人
不是作弊:是生产力工具升级,如同计算器替代心算、IDE 替代手写代码,核心是解决问题;
不会失去学习能力:反而是高效学习方式,可阅读 AI 代码、让 AI 解释、边做项目边学;
不会失去学习能力:反而是高效学习方式,可阅读 AI 代码、让 AI 解释、边做项目边学;
不只能做简单项目:AI 可处理几万行代码、理解复杂业务逻辑、调试复杂 Bug,支持复杂项目开发
不只能做简单项目:AI 可处理几万行代码、理解复杂业务逻辑、调试复杂 Bug,支持复杂项目开发
- 核心思维
- Vibe Coding 不是技术,而是全新的编程思维:让编程从「写代码」变成「表达需求」,从「背语法」变成「说人话」;
- AI 时代,创造力>技术,想法>实现,迭代>完美
布尔(bool)类型
- 作用:表示 “真 / 假”,用于条件判断的结果返回,解决 “是否成立” 类问题(如成绩是否 90 分以上、时间是否为 5:00)。
- 取值:仅包含True(真)和False(假)两个值。
- 非布尔值的真假转换:条件判断中,非布尔类型会自动转为 bool 值
- 数字:0为假,非 0 数字为真;
- 字符串:空字符串""为假,非空字符串为真
比较运算符
- 作用:用于比较两个值的大小、相等关系(等于、大于、小于、大于等于、小于等于),运算结果一定是 bool 类型(True/False)。
- 核心使用场景:判断 “谁大谁小、是否相等、是否满足区间” 等(如年龄 < 35、成绩 > 98)
- 注意:比较时必须是相同的数据类型
逻辑运算符
- 用于连接多个比较条件,实现复杂判断,运算结果仍为 bool 类型,核心有 3 个,结合优先级使用小括号可明确执行顺序
- 运算符 表达式 规则 示例
- and 条件 1 and 条件 2 两个条件同时为真,结果才为真 成绩 > 98 and 积分 > 2000
- or 条件 1 or 条件 2 两个条件一个为真,结果就为真 成绩 = 100 or 排名 < 3
- not not 条件 取 反,条件为真则结果为假 not (年龄 < 18)
- 关键规则
- 优先级控制:多个逻辑运算符连用,用()强制指定执行顺序,提升代码可读性;
- 整体运算符优先级:小括号 () > 算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符=
- Python 中and运算符的规则
- 从左到右依次判断,只要遇到假值,立即返回该假值,不再判断后续条件
- 若所有条件都是真值,返回最后一个真值
选择结构(if 语句)
- 根据条件的真假(bool 值) 执行不同的代码块,Python 中通过缩进区分代码块(缩进一般为 4 个空格),是分支逻辑的核心,分 4 种形式
- 基本 if 结构(单分支)
- if 条件:
- 代码块 # 条件为True时执行,False则跳过
- if-else 结构(双分支)
- if 条件:
- 代码块1 # 条件为True时执行
- else:
- 代码块2 # 条件为False时执行
- 多重 if 结构(多分支:if-elif-else)
- if 条件1:
- 代码块1 # 条件1为True执行
- elif 条件2:
- 代码块2 # 条件1为False、条件2为True执行
- elif 条件3:
- 代码块3 # 前两个条件为False、条件3为True执行
- # 可添加多个elif
- else:
- 代码块n # 所有条件都为False时执行
- 嵌套 if 结构(分支内再嵌套分支)
- if 外层条件:
- # 外层条件为True时,执行内层分支
- if 内层条件1:
- 内层代码块1
- else:
- 内层代码块2
- else:
- 外层代码块 # 外层条件为False时执行
- 注意
- 相匹配的if和else左对齐;
- 内层 if 结构相对于外层,必须缩进
Python 循环结构
循环结构基础
循环结构基础
- 核心特点:由循环条件和循环操作(循环体)组成,满足条件时重复执行操作,直到条件不满足退出,解决重复执行代码的需求。
- 两大循环分类
- 不定循环(while):不知道重复次数,仅知道循环条件时使用。
- 定循环(for):知道明确的循环次数,用于遍历可迭代对象(序列、数字范围等)。
- 通用注意点:必须保证循环能正常退出,避免死循环(循环条件永远为 True)
while 循环
- 使用场景:不知道循环需要执行多少次,仅能通过条件判断控制循环退出(如用户输入验证、数值累加直到满足阈值)
- 基本语法
- while <循环条件>: # 条件为布尔值,True则执行循环体
- <循环体/语句块1>
- else: # 可选,循环条件正常不满足时执行(被break终止则不执行)
- [当有else时表示不满足循环条件后执行,没有表示跳出循环后执行]
- <语句块2>
- 简单示例
- i = 1
- while i <= 10:
- print(i, end=" ")
- i += 1 # 关键:修改循环变量,让条件最终不满足
for 循环
- 使用场景:明确知道循环次数,或需要逐个处理可迭代对象中的元素(如遍历列表、生成固定次数的输入)
- 遍历数字范围(最常用)
- for <变量> in range(begin, end, step):
- <循环体>
- begin:起始数字,默认 0;
- end:结束数字,不包含自身(核心);
- step:步长(每次增量),默认 1,可正可负
- 若只输入一个数字则代表是结束数字。rang(n):表示范围是从0到n-1,不包括n
- 遍历任意可迭代对象
- for <变量> in <可迭代对象>: # 如列表、元组、字符串
- <循环体/语句块1>
- else: # 可选,正常遍历完成执行(被break终止则不执行)
- <语句块2>
循环中的特殊语句
- 语句 核心作用
- pass 空语句,什么也不做,仅用于占位(避免语法错误,如暂未实现的分支 / 循环)
- break 立即跳出整个循环,循环终止,且循环的else分句不会执行
- continue 立即结束本次循环,跳过后续循环体代码,直接进入下一次循环判断
- exit() 直接退出 Python 程序,可指定返回值,后续所有代码都不执行
循环嵌套
- 核心定义
- if、while、for可以互相嵌套,即一个循环的循环体中包含另一个循环(外层循环执行 1 次,内层循环完整执行所有次数)
- 核心使用场景
- 处理二维 / 多维数据、实现多层重复逻辑(如九九乘法表、排列组合问题、矩阵遍历)
- 经典示例
- 九九乘法表(for 嵌套 for)、袋子取球的排列组合(for 嵌套 for)
循环的 else 分句
- 触发条件
- 循环正常结束时执行(while条件为 False、for遍历完所有元素)
- 若循环被 **break语句终止 **,则else分句不会执行
- 示例
- for i in range(3):
- if i == 5:
- break
- print(i)
- else:
- print("循环正常结束") # 会执行,因为没有触发break
- for i in range(3): #表示遍历1,2,3
- if i == 2:
- break
- print(i)
- else:
- print("循环正常结束") # 不执行,因为触发了break
while 与 for 循环的核心区别
- 特性 while 循环 for 循环
- 循环次数 不定,由条件控制 定,由可迭代对象长度控制
- 适用场景 未知循环次数,仅知条件 已知循环次数,遍历元素
- 循环变量 需手动定义和修改 自动遍历,无需手动修改
- 死循环风险 较高(易忘记修改循环变量) 极低(遍历完即终止)
Python 常用数据类型
数字(Number)
数字(Number)
- Python3 支持三种核心数值类型,无单独长整型(Long),整型可无限扩展,是数值计算的基础
- 类型 说明 示例
- 整型(int) 正 / 负整数,无小数点,支持二进制 / 八进制 / 十六进制表示 5、0b100(2)、0xA0F(2575)
- 浮点型(float) 含整数 + 小数部分,支持科学计数法 -21.9、2.5e2(250)
- 复数(complex) 实部 + 虚部构成,虚部以j/J结尾,实部和虚部均为浮点型,多用于科学计算 3+4j、3e+26J
- 常用函数
- Python 内置数学函数(直接调用)
- int(x):将 x 转换为整型
- float(x):将 x 转换为浮点型
- abs(x):返回数字的绝对值
- round(x [,n]):返回 x 的四舍五入值,n 为保留的小数位数
- math 模块函数(需先import math)
- math.ceil(x):上入整数(向上取整,无论小数是几都进 1)
- math.floor(x):下舍整数(向下取整,无论小数是几都舍掉)
- random 模块随机函数(需先import random)
- random.random():返回[0,1)范围内的随机浮点数
- random.randint(a,b):返回[a,b]范围内的随机整数(包含 a 和 b)
- random.uniform(x,y):返回[x,y]范围内的随机浮点数
- random.choice(a):返回变量a中的随机字符
字符串(String)
- Python 中无单字符类型(char),单字符也视为字符串;字符串是不可变序列(无法直接修改单个字符,如s[0]='P'会报错),支持多种创建和操作方式
- 创建方式
- 写法 说明 示例
- 单引号 常规单行字符串 'python666'
- 双引号 与单引号功能一致,支持嵌套单引号 "老师说:'好好学习'"
- 三引号 支持多行字符串,也可用于注释 '''hello<br>world'''
- 转义符\(也代表可接续) 表示特殊字符,如换行(\n)、制表符(\t) "c:\\dd"、"hello\nworld"
- 核心转义字符
- \n:换行;\t:横向制表符(相当于 Tab)
- \\:表示反斜杠本身(如文件路径)
- \'/\":表示单 / 双引号(解决引号嵌套问题)
- 原始字符串:在字符串前加r/R,取消转义,按字面意思显示 print(r'hello\nworld') → hello\nworld
- 核心操作(序列特性)
- 基础操作
- 拼接:+,将多个字符串连接 'hello' + ' ' + 'world' → hello world
- 重复:*,将字符串重复指定次数 'ha'*3 → hahaha
- 成员判断:in/not in,判断子串是否存在 "py" in "python" → True
- 索引与切片(核心)
- 索引从0(正向)开始,-1(反向,从末尾)开始;切片语法:字符串[开始:结束:步长],包含开始,不包含结束
- 正向索引:s = 'python' → s[0]='p'、s[2]='t'
- 反向索引:s[-1]='n'、s[-3]='h'
- 切片示例:
- s[2:5]→tho、s[:3]→pyt(省略开始,从 0 开始)、s[6:]→''(省略结束,到末尾)
- s[::2]→pto(步长 2)、s[::-1]→nohtyp(步长 - 1,字符串反转)
- 长度获取
- len(字符串):返回字符串的字符个数 len('hello') → 5、len('中国') → 2
- 常用内置方法(均返回新字符串,不修改原字符串)
- 方法 说明 示例
- upper() 全部转为大写 'abc'.upper() → ABC
- lower() 全部转为小写 'ABC'.lower() → abc
- strip() 去掉字符串首尾空格(常用作输入清洗) ' hi '.strip() → hi
- replace(a,b) 将字符串中的 a 替换为 b 'a-b-c'.replace('-','_') → a_b_c
- split(sep) 按分隔符 sep拆分字符串为列表,无 sep 则按任意空白拆分,必返回列表 'a,b,c'.split(',') → ['a','b','c']
- join(列表) 将列表中的字符串元素,按指定分隔符合并为新字符串 '-'.join(['a','b','c']) → a-b-c
- startswith(s) 判断字符串是否以 s 开头,返回布尔值 'hello'.startswith('he') → True
- endswith(s) 判断字符串是否以 s 结尾,返回布尔值 'data.txt'.endswith('.txt') → True
- find(s) 从左找子串 s 的首次索引,找不到返回-1 'hello'.find('l') → 2
- rfind(s) 从右找子串 s 的首次索引,找不到返回-1 '1中2中'.rfind('中') → 3
- count(s) 统计子串 s 出现的次数 'banana'.count('a') → 3
- isdigit() 检测字符串是否全为数字,返回布尔值(常用输入验证) '046'.isdigit() → True
- 所有方法都可以跟变量 如 变量a.方法
- 字符串格式化
- f-string(Python3.6+,推荐,简单高效)
- 语法:f"字符串{变量/表达式}",支持直接嵌入变量和表达式
- 示例:name='福耀',age=30 → f"我是{name},明年{age+1}岁" → 我是福耀,明年31岁
列表(List)
- Python 中最常用的可变序列(可修改、增删元素),用[ ]表示,元素类型可任意(数字、字符串、列表等),是存储多个数据的核心容器
- 基本创建
- 语法:列表名 = [元素1, 元素2, ...],元素类型可不同
- 示例:list1 = ['python', 1997, [1,2,3]]、list2 = [1,2,3,4]
- 核心操作(可变特性,可直接修改原列表)
- 索引与切片(与字符串一致)
- 取值:列表[索引] → list1[0] → python
- 切片:列表[开始:结束] → list1[1:] → [1997, [1,2,3]]
- 修改元素
- 语法:列表[索引] = 新值(直接修改指定位置元素)
- 示例:list1[0] = 'java' → list1变为['java', 1997, [1,2,3]]
- 删除元素
- 语法:del 列表[索引](删除指定位置元素,后续元素自动前移)
- 示例:del list1[0] → list1变为[1997, [1,2,3]]
- 遍历列表(核心,常用 for 循环)
- list1 = ['java', 'c', 'python']
- for i in list1:
- print(i) # 依次输出java、c、python
- 常用内置方法(均操作原列表)
- 方法 说明
- len(列表) 返回列表的元素个数(长度)
- max(列表) 返回列表元素的最大值(元素类型需一致,如数字 / 纯字符串)
- min(列表) 返回列表元素的最小值(元素类型需一致)
- append(obj) 在列表末尾追加一个元素(最常用)
- insert(index,obj) 在指定索引位置插入元素,后续元素后移
- remove(obj) 移除列表中第一个匹配obj 的元素
- count(obj) 统计 obj 在列表中出现的次数
- sort() 对原列表进行升序排序(元素类型需一致)
- 示例
- list1 = ['java', 'c', 'python']
- list1.append('php') # 末尾追加 → ['java', 'c', 'python', 'php']
- list1.insert(0, 'js') # 索引0插入 → ['js', 'java', 'c', 'python', 'php']
- list1.remove('c') # 移除c → ['js', 'java', 'python', 'php']
- list1.sort() # 升序排序 → ['java', 'js', 'php', 'python']
元组(Tuple)
- 核心特性:不可变的序列类型,元素仅可访问,无法删除、修改;访问速度快,适合仅需遍历的场景。
- 书写格式:(值1, 值2, ...),单元素元组必须加逗号,如(10,)(若写(10)会被识别为普通数据类型
- 核心特点:不可变、遍历速度比列表快,适合存储不希望被修改的数据
- 基本创建:t1 = (1, 'python', 3.14)、t2 = (1,)(单元素元组需加逗号,否则视为普通变量)
- 操作:支持索引、切片、len ()、in/not in(与字符串 / 列表一致),无增删改方法
- 元素访问
- 按索引访问:元组[索引],如tup1[0]取第一个元素;
- 切片访问:元组[开始位置:结束位置],如tup1[1:3]取索引 1 到 2 的元素(左闭右开)
- 常用函数
- len(元组):获取元素个数
- max(元组):返回最大元素(元素需为可比较类型)
- min(元组):返回最小元素(元素需为可比较类型)
字典(Dictionary)
- 核心特性:可变的键值对(key:value)存储结构,键唯一,值可重复
- 书写格式:{"键1":"值1","键2":"值2", ...},空字典{};
- 键的类型:字符串、数字、元组(不可变类型);
- 值的类型:任意 Python 数据类型
- 基础操作
- 访问元素:字典[键],如dict['b']
- 添加 / 修改元素:字典[键] = 值(键存在则修改,不存在则添加)
- 删除元素:del 字典[键]
- 判断键是否存在:if 键 in 字典:
- 常用函数
- len(字典):返回键值对的个数(字典长度)
- dict.keys():以列表返回所有键
- dict.values():以列表返回所有值
- dict.items():以列表返回可遍历的(键, 值)元组对,适合遍历键值对
- 遍历:通过for k, v in 字典.items():遍历所有键值对
- 输入结果为:k,v
- k,v
- k,v
异常处理
- 异常的定义
- 程序运行时的错误 / 非预期情况,若未处理会导致程序终止并抛出回溯错误信息(如NameError、ZeroDivisionError)
- 核心处理语句:try/except
- try:
- # 可能出现异常的代码
- except 异常类型:
- # 异常发生时的处理逻辑
- 作用:捕获指定异常,程序不崩溃,继续执行后续代码
- 完整结构(try/except/else/finally)
- try:
- # 可能出现异常的代码
- except 异常类型:
- # 异常发生时的处理逻辑
- else:
- # 无异常时执行的代码
- finally:
- # 无论是否有异常,必执行的代码(常用于资源清理:关闭文件/连接)
- 执行流程:出错跳except → 无错执行else → 最终必执行finally
- 多异常处理:分开捕获:多个except语句,分别处理不同异常
- try:
- # 可能出错的代码
- except 异常类型1:
- # 处理异常1
- except 异常类型2:
- # 处理异常2
- 合并捕获:一个except捕获多个异常,用元组表示,可通过as e获取异常信息
- try:
- # 可能出错的代码
- except (异常类型1, 异常类型2) as e:
- print("异常信息:", e)
- 主动抛出异常:raise
- 抛出内置异常:直接raise 异常类型(提示信息),如raise ZeroDivisionError("除数不能为0")
- 自定义异常
- 先定义自定义异常类(继承自Exception);
- 再通过raise抛出;
- class 自定义异常名(Exception):
- pass
- if 条件:
- raise 自定义异常名("自定义提示信息")
- 重新抛出异常:在except中捕获异常后,通过raise再次抛出,让上层代码处理
- try:
- # 可能出错的代码
- except 异常类型:
- pass # 什么都不做,程序继续执行
- 常见内置异常
- ZeroDivisionError:除数为 0 错误
- ValueError:数值类型错误(如输入非数字转整数)
- FileNotFoundError:文件不存在错误
- NameError:变量未定义错误
三大核心序列(字符串 / 列表 / 元组)核心对比
- 特性 字符串(str) 列表(list) 元组(tuple) 字典
- 表示符号 ''/""/'''''' [] () {}
- 可变性 不可变 可变 不可变 可变
- 元素类型 仅字符 任意类型 任意类型 值可以是任意类型
- 索引 / 切片 支持 支持 支持 不支持
- 核心用途 存储文本信息 存储可变的多数据集合 存储不可变的多数据集合 数据的快速查找与关联存储
- 常用操作 拼接、替换、拆分 增删改、追加、排序 仅取值、遍历 增删改、
高频实用场景
- 输入验证:用isdigit()判断是否为纯数字、len()判断长度(如身份证 / 手机号验证)
- 字符串拆分与合并:split()拆分为列表、join()列表合并为字符串(如座机号010-12345678拆分验证)
- 随机数生成:random.randint()生成指定范围随机数(如幸运抽奖)
- 数据存储与修改:用列表存储多个数据,通过append()/insert()/del动态维护
- 字符串清洗:用strip()去掉输入的首尾空格,避免格式错误
Python 函数
函数基础定义与核心规则
函数基础定义与核心规则
- 函数是可重复使用、实现单一 / 关联功能的代码段,能提升代码模块化和复用性
- Python 中自定义函数遵循固定语法规则
- 定义关键字:以def开头,后接函数名 +(参数列表)+ 冒号,无大括号{}
- 函数体:必须统一用空格缩进,是函数的核心功能实现代码
- 文档字符串(可选):函数内第一行用三引号''' '''包裹,用于说明函数功能、参数、返回值,提升代码可读性
- 调用方式:定义完成后,通过函数名([参数值列表])调用,可在其他函数中执行或直接在命令提示符运行
- 命名规范:函数名用小写字母 + 下划线,指定描述性名称,让代码易理解(模块命名也遵循此规则)
- 基础示例(无参函数)
- def display_message():
- '''打印函数功能说明'''
- print("我在学习Python函数!")
- display_message() # 函数调用
函数参数
- Python 函数参数灵活,支持多种类型,定义时的参数顺序有严格要求,不同参数类型适配不同使用场景,文档中重点讲解了 5 类参数
- 位置参数
- 最基础的参数类型,调用时必须按定义顺序传入值,个数需与定义一致;
- 适用于参数数量固定、含义明确的场景
- # 定义:a、b为位置参数
- def add(a, b):
- return a + b
- # 调用:按顺序传参
- print(add(2, 3)) # 输出5
- 默认参数
- 定义时给参数设置默认值,调用时可省略该参数,自动使用默认值;若传参则覆盖默认值;
- 核心规则:默认参数必须放在非默认参数(位置参数)之后,否则报错;
- 适用于参数值相对固定、偶尔需要修改的场景
- # 定义:name为位置参数,age为默认参数(默认值18)
- def greet(name, age=18):
- print(f"你好{name},今年{age}岁")
- # 调用1:省略默认参数
- greet("小明") # 输出:你好小明,今年18岁
- # 调用2:覆盖默认参数
- greet("小红", 20) # 输出:你好小红,今年20岁
- 关键字参数
- 调用时通过参数名=值的方式传参,顺序可与定义不一致
- 适用于参数较多的场景,避免因位置记错导致传参错误
- 混合传参时,位置参数必须在前,关键字参数在后
- # 定义:name、age为位置参数
- def show_info(name, age):
- print(f"姓名:{name},年龄:{age}")
- # 调用:关键字传参,顺序无关
- show_info(age=28, name="福耀") # 输出:姓名:福耀,年龄:28
- # 混合传参(规范)
- show_info("Tom", age=20) # 输出:姓名:Tom,年龄:20
- 可变位置参数(*args)
- 用*args定义,可接收任意数量的位置参数,传入的参数会被封装成元组
- 适用于预先不知道需要多少个位置参数的场景(如求和、拼接)
- # 定义:*args接收任意数量的位置参数
- def sum_all(*args):
- return sum(args)
- # 调用:传入任意个数的参数
- print(sum_all(1,2,3)) # 输出6
- print(sum_all(5,10,15,20)) # 输出50
- 可变关键字参数(**kwargs)
- 用**kwargs定义,可接收任意数量的关键字参数,传入的参数会被封装成字典(key 为参数名,value 为参数值);
- 适用于接收任意配置参数的场景(如用户信息、对象属性),是文档中强调的最常见用法
- # 定义:**kwargs接收任意数量的关键字参数
- def show_user_info(**kwargs):
- # 逐行打印键值对
- for k, v in kwargs.items():
- print(f"{k} : {v}")
- # 调用:传入任意个数的关键字参数
- show_user_info(name="Tom", age=20, city="Beijing")
- 参数定义总顺序
- 定义函数时,多种参数混合使用的唯一正确顺序:普通位置参数 → *args → 默认参数 → **kwargs
- # 正确示例
- def func(a, b, *args, c=10, **kwargs):
- pass
- # 错误示例(默认参数放*args前)→ 直接报错
- # def func(a, b, c=10, *args, **kwargs):
- # pass
函数返回值
- 通过return [表达式]结束函数,将结果返回给调用方,无 return 则默认返回None,是函数传递计算结果的核心方式
- 返回单个值
- 直接返回一个表达式的结果,调用方可将结果赋值给变量或直接使用
- def get_sum(x, y):
- return x + y
- # 赋值给变量
- res = get_sum(3,5)
- print(res) # 输出8
- # 直接使用
- print(get_sum(10,20)) # 输出30
- 返回多个值
- Python 中无真正的 “多返回值”,实际是将多个值封装成元组返回,调用方可通过解包直接接收多个变量
- def calc(a, b):
- # 等价于 return (a+b, a-b)
- return a + b, a - b
- # 解包接收多返回值
- sum_, diff = calc(10,5)
- print(sum_, diff) # 输出15 5
- 无 return
- 函数未写 return 语句时,默认返回 None,此类函数一般用于执行打印、修改变量等无返回结果的操作
- def print_hello():
- print("Hello Python")
- res = print_hello()
- print(res) # 输出None
变量作用域
- 变量的可访问范围,文档中重点区分全局变量和局部变量,核心规则围绕 “函数内 / 外的变量访问与修改
- 局部变量
- 定义在函数内部的变量,拥有局部作用域
- 仅能在定义它的函数内部访问,函数执行结束后,局部变量会被销毁
- 全局变量
- 定义在函数外部的变量,拥有全局作用域
- 可在整个模块中访问(包括函数内部直接读取)
- 全局变量的修改(global 关键字)
- 函数内部直接读取全局变量无需额外关键字;
- 函数内部修改全局变量时,必须用global 变量名声明,告诉解释器 “当前使用的是全局变量,而非局部变量”
- # 定义全局变量
- x = 10
- def func():
- global x # 声明使用全局变量x
- x += 1 # 修改全局变量
- print(x) # 输出11
- func()
- print(x) # 输出11(全局变量被修改)
- 作用域核心示例
- 函数内定义与全局变量同名的变量,会被视为局部变量,不会影响全局变量
- total = 0 # 全局变量
- def sum_num(arg1, arg2):
- total = arg1 + arg2 # 局部变量,与全局变量同名
- print("函数内局部变量:", total) # 输出30
- return total
- sum_num(10,20)
- print("函数外全局变量:", total) # 输出0(全局变量未被修改)
Python 类型提示
- 基础用法
- 在参数后用:指定参数类型,在函数后用->指定返回值类型
- # 提示a、b为int类型,返回值为int类型
- def add(a: int, b: int) -> int:
- return a + b
- 联合类型
- 从typing模块导入Union,指定参数 / 变量可为多种类型之一
- from typing import Union
- # 提示q可为str类型或None
- q: Union[str, None] = None
- # 提示参数x可为int或float,返回值为int或float
- def square(x: Union[int, float]) -> Union[int, float]:
- return x ** 2
- 作用
- 给编辑器 / IDE(PyCharm、VSCode)、静态检查工具(mypy)提供提示,减少语法错误
- 给框架(FastAPI)提供支持,帮助自动做数据解析
- 给开发者提供阅读提示,让代码更 “自解释
函数的核心优势
- 代码复用:编写一次,可通过调用重复使用,避免冗余代码
- 易维护:修改函数内的代码块,所有调用该函数的地方都会同步更新,无需逐个修改
- 易阅读:描述性的函数名能概述代码功能,阅读函数调用比阅读原生代码块更高效
- 易测试:单个函数实现单一功能,可单独测试每个函数的正确性,降低程序调试难度
Python 类与对象
核心概念:Python 一切皆对象
核心概念:Python 一切皆对象
- 对象:Python 中所有数据类型(int/str/list)、函数、类本身,都是对象(实例);对象是类的具体体现。
- 类:是创建对象的模具 / 模板,定义了对象的属性(变量,描述特征)和方法(函数,描述行为),同一类的对象共享类的定义,拥有独立的实例数据。
- 类与对象的关系:类是抽象的模板,对象是类的具体实例(比如int是类,a=10的a是int的对象;Dog是自定义类,d1=Dog("小黑",3)的d1是Dog的对象)
- # 内置类型的类与对象
- a = 10 # a是int类的对象
- b = [1,2,3] # b是list类的对象
- print(type(a)) # <class 'int'> 打印对象所属的类
- print(type(b)) # <class 'list'>
类的基础定义与实例化
- 类的定义语法
- 以class关键字开头,后接类名(大驼峰命名法:首字母大写,如 Dog/Student)+ 冒号,函数体缩进(统一空格),包含属性和方法
- class 类名:
- # 类属性(可选)
- 类属性名 = 取值
- # 构造方法(初始化对象,必选核心)
- def __init__(self, 参数1, 参数2):
- self.实例属性1 = 参数1 # 定义实例属性
- self.实例属性2 = 参数2
- # 自定义方法(可选,描述行为)
- def 方法名(self, 形参):
- 方法体(可操作实例/类属性)
- 构造方法 __init__
- 又称初始化方法 / 构造函数,是创建对象时自动调用的特殊方法,用于给对象初始化实例属性(对象属性);
- 第一个参数必须是self(不可省略),self代表对象本身,创建对象时解释器会自动将对象传入self;
- 自定义的形参在self后,用于接收创建对象时传入的属性值
- 对象的实例化(创建对象)
- 语法:对象名 = 类名(实参),实参个数与__init__中self后的形参一致,创建后可通过对象名.属性/方法操作
- # 示例:定义Dog类并实例化
- class Dog:
- # 类属性
- species = "犬科"
- # 构造方法:初始化实例属性name/age
- def __init__(self, name, age):
- self.name = name
- self.age = age
- # 自定义实例方法
- def bark(self):
- print(f"{self.name} 汪汪叫!")
- # 实例化:创建2个Dog对象
- d1 = Dog("小黑", 3)
- d2 = Dog("旺财", 2)
- # 访问对象的属性和方法
- print(d1.name) # 小黑(访问实例属性)
- print(d1.species) # 犬科(访问类属性)
- d2.bark() # 旺财 汪汪叫!(调用实例方法)
核心区分:类属性 vs 实例属性
- 类的属性分为类属性和实例属性,对应 Java 的静态成员变量和实例成员变量,核心区别是作用范围和访问方式
- 类型 定义位置 访问方式 作用范围 特点
- 类属性 类内部、所有方法外部 类名。属性名 / 对象。属性名 所有实例共享 修改变量时,所有实例同步生效
- 实例属性 构造方法__init__内部 仅能通过对象。属性名访问 每个实例独立拥有 修改一个对象的属性,不影响其他对象
- class Test:
- x = 100 # 类属性:所有Test对象共享
- def __init__(self, y):
- self.y = y # 实例属性:每个对象独立
- a = Test(1)
- b = Test(2)
- # 1. 访问类属性:类名/对象均可
- print(a.x, b.x) # 100 100
- # 2. 修改类属性:通过类名修改,所有实例同步
- Test.x = 200
- print(a.x, b.x) # 200 200
- # 3. 访问/修改实例属性:仅对象可操作,相互独立
- a.y = 10
- print(a.y, b.y) # 10 2(b.y未被修改,仍为初始值)
- 类属性建议通过类名访问 / 修改,更符合设计逻辑;
- 实例属性不能通过类名访问,会直接报错;
- 若对象定义了与类属性同名的实例属性,会覆盖类属性(仅对当前对象生效)
方法的分类:实例方法 / 类方法 / 静态方法
- 类中的方法分为三类,核心区别是第一个参数、依赖关系和调用方式,其中实例方法是最常用的类型,类方法和静态方法为拓展类型
- 方法类型 定义标识 第一个参数 核心特点 调用方式 适用场景
- 实例方法 无装饰器,直接 def 定义 self 依赖对象,可操作实例 / 类属性 仅能通过对象调用 操作对象的专属属性 / 行为(最常用)
- 类方法 装饰器@classmethod cls 依赖类,仅操作类属性 类名。方法名 / 对象。方法名 对类属性进行统一修改 / 操作
- 静态方法 装饰器@staticmethod 无默认参数 不依赖类 / 对象,独立功能 类名。方法名 / 对象。方法名 类的辅助功能,与类 / 对象属性无关
- class Example:
- version = "1.0" # 类属性
- # 1. 实例方法
- def instance_method(self):
- print("这是实例方法,依赖对象:", self)
- # 2. 类方法
- @classmethod
- def class_method(cls):
- print("这是类方法,操作类属性:", cls.version)
- # 3. 静态方法
- @staticmethod
- def static_method():
- print("这是静态方法,独立功能")
- e = Example()
- # 调用方式
- e.instance_method() # 实例方法:仅对象可调用
- Example.class_method() # 类方法:推荐类名调用
- Example.static_method() # 静态方法:推荐类名调用
- 实例方法的self、类方法的cls都是解释器自动传入,调用时无需手动传参
- 静态方法无默认参数,定义和调用与普通函数一致,只是归属在类的命名空间中
面向对象核心特性:封装
- 封装的概念
- 将类的数据(属性)和操作数据的方法封装在一起,隐藏内部实现细节,限制外部直接访问 / 修改属性,
- 仅通过类提供的方法操作数据,保证数据的安全性
- 私有属性 / 方法(实现封装的核心)
- Python 中无严格的访问修饰符(如 Java 的 private/public),通过属性 / 方法名前加两个下划线__定义私有成员,
- 实现 “外部不可直接访问” 的效果
- 私有属性:__属性名,仅能在类的内部访问 / 修改,外部直接对象.__属性名会报错;
- 私有方法:__方法名,仅能在类的内部调用,外部不可直接调用;
- 实操思路:通过公有方法(普通实例方法)封装对私有属性的操作(如存钱 / 取钱方法操作私有余额)
- class Account:
- def __init__(self, owner):
- self.owner = owner # 公有属性:外部可访问
- self.__balance = 0 # 私有属性:余额,外部不可直接修改
- # 公有方法:存钱(操作私有属性__balance)
- def deposit(self, amount):
- if amount > 0:
- self.__balance += amount
- print(f"存钱{amount}成功,当前余额:{self.__balance}")
- else:
- print("存钱金额必须大于0")
- # 公有方法:取钱(操作私有属性__balance)
- def withdraw(self, amount):
- if 0 < amount <= self.__balance:
- self.__balance -= amount
- print(f"取钱{amount}成功,当前余额:{self.__balance}")
- else:
- print("取钱金额无效或余额不足")
- # 公有方法:显示余额(外部查看余额的唯一方式)
- def show(self):
- print(f"账户{self.owner}的余额:{self.__balance}")
- # 实例化
- acc1 = Account("张三")
- # 外部操作:仅能通过公有方法访问/修改私有余额
- acc1.deposit(1000) # 存钱1000成功,当前余额:1000
- acc1.withdraw(500) # 取钱500成功,当前余额:500
- acc1.show() # 账户张三的余额:500
- # acc1.__balance # 直接访问私有属性:报错AttributeError
特殊方法:魔术方法
- 以双下划线开头和结尾的方法(__xxx__),又称魔术方法 / 特殊方法,是 Python 内置的方法,无需手动调用,
- 在特定场景下由解释器自动触发,文档重点讲解了核心魔术方法,补充常用拓展
- 魔术方法 触发场景 核心作用 示例
- __init__ 创建对象时(实例化) 初始化对象的实例属性 def __init__(self, name): self.name=name
- __str__ 打印对象时(print(对象)) 定义对象的字符串输出格式 返回自定义字符串,替代默认的内存地址
- __len__ 调用len(对象)时 定义对象的 “长度” 计算规则 适用于自定义容器类对象
- __eq__ 调用对象1 == 对象2时 定义对象的相等判断规则 自定义属性比较逻辑
- class Book:
- def __init__(self, name, pages):
- self.name = name
- self.pages = pages
- # 重写__str__:自定义打印对象的输出格式
- def __str__(self):
- return f"《{self.name}》共{self.pages}页"
- b = Book("Python入门", 300)
- print(b) # 触发__str__,输出:《Python入门》共300页
- # 若不重写__str__,print(b)会输出对象的内存地址(如<__main__.Book object at 0x000001>)
- 拓展常用魔术方法
- __del__:对象被销毁时触发,用于释放资源;
- __add__:调用对象1 + 对象2时触发,自定义对象的加法规则;
- __getitem__:通过对象[索引]访问时触发,模拟容器类的索引操作
类的继承
- 继承的概念:让一个子类(派生类)继承父类(基类)的所有属性和方法,子类可重写父类方法或新增自己的属性 / 方法,实现代码复用
- 语法:class 子类名(父类名):
- super()函数:子类中调用super()可获取父类的对象,用于调用父类的方法(如super().speak()调用父类的speak方法)
- 方法重写:子类定义与父类同名的方法,覆盖父类的方法实现,体现子类的个性化
- # 父类:Animal
- class Animal:
- def speak(self):
- print("动物发出叫声")
- # 子类:Dog 继承 Animal
- class Dog(Animal):
- # 方法重写:覆盖父类的speak
- def speak(self):
- super().speak() # 调用父类的speak方法
- print("狗汪汪叫")
- d = Dog()
- d.speak()
- # 输出:
- # 动物发出叫声
- # 狗汪汪叫
Python 文件读写
Python 文本文件读写
Python 文本文件读写
- 文件基础概念
- 文本文件:由若干行字符构成,可通过文本编辑器编辑,后缀如txt/htm/py/csv等;
- 本质也是二进制文件,是计算机对二进制数据的字符编码解析后的形式
- 二进制文件:有特定格式,无法用文本编辑器直接编辑,如音视频、图片、安装包等,需专用软件处理(如 PS 编辑图片)
- 文件的打开与关闭
- fileObject = open(filename, mode) # filename:文件路径;mode:打开方式,返回文件对象
- 核心打开方式
- 方式 功能 适用场景 注意事项
- r 只读(默认) 仅读取文件内容 文件不存在则报错
- w 只写,打开时清空原有内容 全新写入文件 文件不存在则创建
- a 追加,写入仅在文件末尾 补充写入文件 文件不存在则创建
- rb/wb/ab 二进制模式的读 / 写 / 追加 操作二进制文件(图片 / 视频) 读取返回字节串,写入需传字节串
- + 追加读写功能(跟在其他模式后) 同时读写文件 r+:不清空,可任意位置写;a+:仅末尾写;w+:先清空再读写
- 关闭文件
- fileObject.close() # 必做:处理缓存数据,释放文件资源
- 推荐写法:使用with open(...) as f,自动关闭文件,无需手动调用close(),避免忘记关闭导致资源泄漏
- with open("test.txt", "r") as f:
- content = f.read()
文件异常处理(针对读文件)
- 当以带 r 的方式打开文件时,文件不存在会抛出FileNotFoundError,需用try-except捕获,保证程序健壮性
- try:
- f = open("readfile.txt", "r") # 可能触发异常的代码
- except FileNotFoundError:
- print("文件不存在,请检查路径!") # 异常处理逻辑
- 扩展:可捕获通用异常Exception处理未知错误,或多异常捕获适配多种场景
文件指针
- 概念:每个打开的文件都有隐含的指针,标记当前读写位置,以字节数为单位从文件头部计算
- 初始位置:r/w模式→文件头部;a模式→文件尾部
- 核心操作函数
- 获取指针位置:L = fp.tell() → 返回当前指针到文件头部的字节数。
- 移动指针位置:fp.seek(offset, from_what)
- offset:偏移的字节数(正数向后移,负数向前移);
- from_what:偏移基准(0 = 文件头部 <默认>,1 = 当前位置,2 = 文件尾部)
- with open("test.txt", "r") as f:
- f.seek(6, 0) # 从文件头部向后移6个字节
- print(f.tell()) # 输出6,当前指针位置
读文件核心函数(3 个 + 1 种迭代方式)
- 文件对象为f,所有读函数均从当前指针位置开始读取,读取后指针自动后移
- 函数 用法 返回值 适用场景
- read() f.read() 整个文件的字符串 小文件一次性读取
- read(N) f.read(N) 读取 N 个字符的字符串 按需读取指定长度
- readline() f.readline() 读取一行的字符串(含换行符\n) 逐行读取大文件,节省内存
- readlines() f.readlines() 列表,每个元素为文件的一行字符串(含\n)需对所有行做列表操作时
- for 循环迭代 for line in f: 逐行返回字符串 大文件逐行处理(最优方式,无需手动管理指针)
- 注意:中文等多字节字符,1 个字符≠1 个字节,read(N)按字符计数,seek/tell按字节计数
写文件核心函数(2 个)
- 注意:写函数不会自动添加换行符,需手动加\n,否则内容会拼接在一起
- 函数 用法 说明 示 例
- write() f.write(str) 写入单个字符串,返回写入的字符数 f.write("Python\n")
- writelines() f.writelines(seq) 写入序列(列表 / 元组),序列元素必须是字符串 f.writelines(["Java\n", "C++\n"])
文件读写进阶:数字类型处理
- 文件中存储的内容均为字符串,读写数字(int/float)需手动类型转换,是学生成绩 / 数据统计的核心考点
- 写数字:用str()将数字转为字符串后写入;
- 读数字:用int()/float()将读取的字符串转为数字后运算
- 经典示例:输入学生成绩写入文件,读取后计算平均分
- # 写入成绩(数字转字符串)
- with open("grade.txt", "w") as f:
- name = "张三"
- math = 90
- english = 85
- f.write(f"{name} {math} {english}\n") # 数字直接拼接到字符串,自动转义
- # 读取成绩并计算平均分(字符串转数字)
- with open("grade.txt", "r") as f:
- for line in f:
- line = line.strip() # 去掉首尾空格/换行符
- name, m, e = line.split() # 按空格拆分字符串
- avg = (float(m) + float(e)) / 2 # 转浮点型后运算
- print(f"{name} 平均分:{avg}")
其他常用函数
- flush():f.flush() → 立即将缓冲区的内容写入硬盘,无需等待文件关闭(适用于实时写入场景);
- truncate([size]):f.truncate(10) → 截断文件,仅保留前size个字节,无size则从当前指针位置截断,后续内容全部删除
Python 操作 MySQL 数据库
PyMySQL 基础
PyMySQL 基础
- 作用:Python3.x 中连接 MySQL 服务器的第三方库,实现 Python 对 MySQL 的增删改查(CRUD);
- 安装:命令行执行pip install PyMySQL;
- 验证安装:Python 环境中输入import pymysql,无报错则安装成功
PyMySQL 核心操作步骤
- 核心原则:增 / 删 / 改需提交事务,查询无需;所有操作建议加异常处理,出错则回滚事务
- import pymysql # 步骤1:引入模块
- try:
- # 步骤2:建立数据库连接
- conn = pymysql.connect(
- host="localhost", # 数据库主机地址(本地为localhost)
- port=3306, # MySQL端口(默认3306,整数类型)
- user="root", # 数据库用户名
- password="123456", # 数据库密码
- database="students", # 要操作的数据库名
- charset="utf8mb4" # 字符集(推荐utf8mb4,支持所有中文/Emoji)
- )
- # 步骤3:获取游标对象(执行SQL的工具)
- cur = conn.cursor() # 默认返回元组结果,可加pymysql.cursors.DictCursor返回字典
- # 步骤4:执行SQL语句(增删改查)
- # SQL参数用%s占位,参数值传元组/列表,避免SQL注入
- cur.execute("select * from student where id=%s", (1,))
- # 步骤5:处理结果/提交事务
- res = cur.fetchall() # 查询:获取结果;增删改:conn.commit()提交事务
- print(res)
- except Exception as e:
- conn.rollback() # 出错回滚事务,恢复数据原状
- print("操作失败:", e)
- finally:
- # 步骤6:关闭连接(先关游标,再关连接)
- cur.close()
- conn.close()
关键知识点:游标与 SQL 执行
- 游标对象:cur = conn.cursor(),是执行 SQL 的载体,操作完成后必须关闭;
- 扩展:cur = conn.cursor(pymysql.cursors.DictCursor) → 查询结果返回列表嵌套字典,按字段名取值更直观,无需记索引
- SQL 执行函数:cur.execute(sql, args)
- sql:要执行的 SQL 语句,参数用 % s 占位(无论参数是数字 / 字符串)
- args:SQL 的参数值,传元组 / 列表(单个参数需加逗号,如(1,))
- 返回值:受影响的行数(增删改查均返回,查询返回匹配的行数)
增 / 删 / 改 / 查 核心实现
- 插入数据(INSERT)
- cur.execute("insert into student(name,gender,score) values(%s,%s,%s)", ("李四", "女", 92))
- conn.commit() # 必须提交事务,否则数据不写入数据库
- print(f"插入{cur.rowcount}行数据") # cur.rowcount:受影响行数
- 修改数据(UPDATE)
- 必加 WHERE 条件,否则修改整张表的所有数据!
- cur.execute("update student set score=%s where id=%s", (95, 1))
- conn.commit()
- 删除数据(DELETE)
- 必加 WHERE 条件,否则删除整张表的数据!
- cur.execute("delete from student where id=%s", (2,))
- conn.commit()
- 查询数据(SELECT)
- 无需提交事务,通过fetchall()/fetchone()获取结果,默认返回元组嵌套元组
- 函数 用法 返回值 适用场景
- fetchall() cur.fetchall() 所有匹配的结果,元组 / 字典列表 查询多条数据
- fetchone() cur.fetchone() 第一条匹配的结果,元组 / 字典 查询单条数据
- # 默认游标:返回((1, '李四', '女', Decimal('95.0')),)
- cur.execute("select * from student")
- all_data = cur.fetchall()
- for row in all_data:
- id, name, gender, score = row
- print(f"{name} 成绩:{float(score)}") # Decimal转float/int运算
- # 字典游标:返回[{'id':1, 'name':'李四', 'gender':'女', 'score':Decimal('95.0')}]
- cur = conn.cursor(pymysql.cursors.DictCursor)
- cur.execute("select * from student")
- all_data = cur.fetchall()
- for row in all_data:
- print(f"{row['name']} 成绩:{float(row['score'])}")
事务处理
- 事务概念:将一组 SQL 操作视为一个整体,要么全部执行成功,要么全部失败(保证数据一致性)
- PyMySQL 事务默认开启,因此增 / 删 / 改后必须执行conn.commit(),否则操作仅在内存中,未真正写入数据库
- 回滚:出错时执行conn.rollback(),恢复到事务执行前的状态,避免数据错乱
- 查询操作:无需提交 / 回滚事务,因为查询不修改数据库数据
常见数据类型适配
- MySQL 中的部分数据类型,PyMySQL 查询后会返回专属类型,需转换后使用
- DECIMAL/DOUBLE/FLOAT:返回Decimal类型,需用float()/int()转为普通数字后运算 / 输出;
- DATETIME/DATE:返回datetime对象,可直接打印或用str()转为字符串
文件读写避坑点
- 路径问题
- 相对路径:open("test.txt") → 以Python 程序运行目录为基准;
- 绝对路径:Windows 用\\(转义)或r"路径"(原生字符串),如open(r"C:\Python\test.txt");Linux/Mac 用/,如open("/home/Python/test.txt")
- 编码问题
- 打开中文文件时,指定编码encoding="utf-8",避免乱码
- with open("test.txt", "r", encoding="utf-8") as f:
- content = f.read()
- 换行符问题
- Windows 换行符为\r\n,Linux/Mac 为\n,line.strip()可统一去掉首尾的换行 / 空格
PyMySQL 避坑点
- 字符集问题:连接时指定charset="utf8mb4",而非utf8(MySQL 的utf8仅支持部分中文,会导致生僻字 / Emoji 插入失败)
- 枚举类型(ENUM):插入值必须与表定义的枚举值完全一致(如ENUM('男','女'),不可插入'nan'/'female'),否则触发DataError
- 自增主键:MySQL 中自增字段(AUTO_INCREMENT),插入时无需手动传值,由数据库自动生成,避免主键冲突
- SQL 语法错误:UPDATE/INSERT 的多个字段间必须加逗号,WHERE 条件与 SET/VALUES 间必须加空格,否则触发ProgrammingError
- 数据库切换:操作指定数据库的表,需在connect中指定database,或先执行cur.execute("use 数据库名"),否则默认操作mysql系统库,
- 触发Table doesn't exist错误
文件与数据库结合场景
- 实际开发中,常需从文件读取数据写入数据库,或从数据库查询数据写入文件,核心逻辑为「文件读写的类型转换 + PyMySQL 的增 / 查操作」
- 示例:从 grade.txt 读取学生成绩,写入 MySQL 的 student 表
- import pymysql
- # 建立数据库连接
- conn = pymysql.connect(host="localhost", user="root", password="123456", database="students", charset="utf8mb4")
- cur = conn.cursor()
- # 从文件读取数据
- with open("grade.txt", "r", encoding="utf-8") as f:
- for line in f:
- line = line.strip()
- if not line:
- continue
- name, math, english = line.split()
- # 计算平均分,写入数据库
- avg_score = (float(math) + float(english)) / 2
- cur.execute("insert into student(name,score) values(%s,%s)", (name, avg_score))
- conn.commit()
- cur.close()
- conn.close()
- print("数据导入完成!")
核心考点与实操总结
- 文件读写:重点掌握with open的使用、3 个读函数、2 个写函数、数字类型的转换,以及文件不存在的异常处理
- PyMySQL:固定 6 步操作流程,重点掌握增删改查的 SQL 执行、事务提交 / 回滚、参数占位 % s 的使用,以及查询结果的处理
- 核心关联:文件是数据的本地存储形式,数据库是数据的结构化存储形式,二者的转换核心是字符串与其他数据类型的相互转换
- 避坑核心:文件操作注意路径和编码,数据库操作注意SQL 语法、事务处理和数据类型匹配
docker
核心定义
核心定义
- Docker 是一款容器化引擎,能将应用程序及其依赖环境打包成标准化的「镜像」,通过「容器」运行
- 实现跨环境的一致性部署(解决 “本地能跑、服务器跑不了” 的问题),基于Cgroups和Namespace和UnionFS
- Namespace:给容器做隔离,让容器看不见宿主机和其他容器的资源(进程、网络、文件等)
- Cgroups:给容器做限制,控制容器能用多少 CPU、内存、磁盘 I/O 等资源
Docker 三大核心技术
- Namespace:资源隔离(PID、网络、文件系统各自独立)
- Cgroups:资源限制(CPU、内存、带宽限制)
- OverlayFS:镜像分层、写时复制
容器 vs 虚拟机
- 容器共用宿主机内核,虚拟机有独立内核
- 容器轻量、秒启动;虚拟机重、启动慢
- 容器占用资源少;虚拟机占用资源多
- 核心:Docker 是应用隔离,共用内核;虚拟机是系统隔离,独享内核
3 个核心概念
- 概念 通俗理解 核心特点
- 镜像(Image) 应用的 “安装包 / 模板” 只读、可复用、可分层构建
- 容器(Container) 镜像运行后的 “实例” 独立隔离、可启停 / 删除、轻量
- 仓库(Registry) 存储镜像的 “仓库” 官方仓库:Docker Hub
docker镜像的原理
- Docker 镜像就是一个只读的模板,分层结构,容器启动时会在最上面加一层可写层(增量构建),修改只在容器里,镜像本身不变(读写分离)
- 镜像由多层只读文件系统(UnionFS)叠加而成。
- 基础镜像层(如 CentOS)是所有容器共享的只读层。
- 每次构建新指令(如RUN、COPY)都会生成一个新的只读层。
- 容器启动时,会在镜像最上层加一层可写层,所有修改都发生在这一层。
- 优点:节省存储空间、加速镜像构建和分发。
核心价值
- 环境统一:开发 / 测试 / 生产环境完全一致
- 轻量高效:比虚拟机省资源,秒级启动 / 停止
- 隔离性好:多个容器互不干扰
- 易迁移:镜像可在任意支持 Docker 的机器上运行
Docker 镜像分层有什么好处
- 镜像层共享:多个镜像共用基础层,节省磁盘空间;
- 增量构建:修改只新增一层,不用重新打包全部内容,构建更快;
- 读写分离:底层镜像只读,容器上层可写,保证镜像安全、不可篡改。
Docker 为什么能够高效运行
- 分层镜像复用:镜像由只读层叠加而成,不同镜像共享底层,减少重复存储 / 下载,修改时仅更新差异层(写时复制)
- 轻量化打包:仅包含服务必需依赖,无冗余系统组件,镜像体积远小于虚拟机
- 共享主机内核:容器无独立内核,直接复用宿主机内核,省略系统启动环节,秒级启动(虚拟机需加载完整内核,分钟级启动)
Docker 常用命令
- docker pull 镜像名[:版本] #拉取镜像(默认latest,生产建议指定版本如nginx:1.25.3)
- docker pull IP:端口/镜像名 #本地拉取镜像
- docker images #查看本地所有镜像
- -qa #查看所有的镜像id q仅查看id a查看所有
- docker rmi 镜像ID/镜像名[:版本] #删除镜像(需先删除依赖该镜像的容器)
- docker search 镜像名 #搜索镜像(Docker Hub上)
- docker run -d -p 8080:80 --name 容器名 镜像名[:版本]
- # 1. 运行容器(创建+启动)-d:后台运行;-p 主机端口:容器端口:端口映射;--name:自定义容器名
- -it:以交互式运行容器,只要是通过这个方式运行的在命令最后一定要加/bin/bash或sh
- docker ps #查看运行中的容器
- docker ps -a #查看所有容器(包括停止的)
- docker start 容器ID/容器名 #启动/停止/重启容器
- docker stop 容器ID/容器名
- docker restart 容器ID/容器名
- docker top 容器名/容器ID #查看容器内部运行的进程
- docker stats 容器ID/容器名 #查看容器信息资源,可以查看容器的资源使用情况
- docker rm 容器ID/容器名 #删除容器(需先停止)
- docker exec -it 容器ID/容器名 /bin/bash #进入容器内部(调试用)
- docker logs 容器ID/容器名 #查看容器日志(排查问题)
- systemctl status docker #查看Docker状态(Linux)
- systemctl start docker #启动/停止Docker服务(Linux)
- systemctl stop docker
- docker -v # 查看Docker版本
- docker version
- docker save -o 自定义名字.tar 本地镜像名[:版本] #导出(保存)镜像为 tar 包
- docker load -i 自定义名字.tar #导入(加载)tar 包为镜像
- docker commit #导出正在运行的容器,生成为一个新的镜像
- docker system prune #清理停止的容器、无用网络、镜像缓存
- -a #强制删除
关键注意点
- latest 标签:仅为默认标签,不代表 “最新稳定版”,生产环境务必指定具体版本
- 端口映射:-p 参数是容器对外提供服务的核心,主机端口不能被占用
- 容器删除:必须先停止容器,否则需加 -f 强制删除(docker rm -f 容器ID),但不建议强制操作
总结
- Docker 核心是「镜像(模板)+ 容器(实例)」,解决环境不一致和部署效率问题及应用版本问题
- 高频命令优先掌握:pull/run/ps/start/stop/rm(镜像 + 容器的增删改查)
- 运行容器的核心参数:-d(后台)、-p(端口映射)、--name(命名)
安装docker
- 将网卡的static改为dhcp
- cat>/etc/yum.repos.d/CentOS-Media.repo <<EOF
- [c7-media]
- name=local
- baseurl=ftp://192.168.5.24/linux_soft/
- gpgcheck=0
- enabled=1
- EOF
- sudo yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 学校镜像源
- cat > /etc/docker/daemon.json <<EOF
- {
- "insecure-registries": ["192.168.5.24:5000"],
- "registry-mirrors": [
- "https://ccr.ccs.tencentyun.com",
- "https://docker.rainbond.cc",
- "https://elastic.m.daocloud.io",
- "https://elastic.m.daocloud.io",
- "https://docker.m.daocloud.io",
- "https://gcr.m.daocloud.io",
- "https://ghcr.m.daocloud.io",
- "https://k8s-gcr.m.daocloud.io",
- "https://k8s.m.daocloud.io",
- "https://mcr.m.daocloud.io",
- "https://nvcr.m.daocloud.io",
- "https://quay.m.daocloud.io"
- ]
- }
- EOF
- 阿里云 Docker 镜像源
- vim /etc/docker/daemon.json
- {
- "registry-mirrors": [
- "https://0vmzj3q6.mirror.aliyuncs.com",
- "https://docker.m.daocloud.io",
- "https://mirror.baidubce.com",
- "https://dockerproxy.com",
- "https://mirror.iscas.ac.cn",
- "https://huecker.io",
- "https://dockerhub.timeweb.cloud",
- "https://noohub.ru",
- "https://vlgh0kqj.mirror.aliyuncs.com",
- "https://7u57wo6o.mirror.aliyuncs.com",
- "https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
- ]
- }
- systemctl restart docker
docker 创建镜像
Dockerfile 基础规则
Dockerfile 基础规则
- 指令首字母大写,按执行顺序编写,FROM 必须是第一个命令
- 每条指令执行后生成一层新镜像,尽量合并命令减少分层(用&&连接),避免镜像膨胀
- 注释用#开头,构建上下文为docker build后指定的目录(.代表当前目录)
核心指令
- 指令 核心作用 & 关键说明
- FROM 指定基础镜像(镜像构建的基础模板),推荐极简镜像alpine/ 业务专属镜像(Java 用 openjdk、Web 用 nginx)
- WORKDIR 设置容器工作目录,后续RUN/COPY/CMD等指令均在此目录执行,等效cd,推荐使用避免路径混乱
- COPY 宿主机→容器复制文件,推荐使用,仅做单纯复制,不解压、不支持网络资源
- RUN 构建镜像阶段执行命令,用于安装依赖、编译环境(如apt-get install),容器启动前已执行
- EXPOSE 声明容器对外暴露的端口,仅做说明,不实际映射,运行容器时需用-p/-P发布端口
- CMD 容器启动时执行的默认命令,仅生效最后一个,可被docker run后参数覆盖
- ENTRYPOINT 容器启动时固定执行的命令,不可被覆盖,docker run后参数会拼接在其后,常与CMD配合使用
- ENV 设置全局环境变量,容器运行时可直接调用(如ENV JAVA_HOME=/usr/lib/jvm),支持多变量换行 ()
- ADD 宿主机→容器复制文件,慎用,可自动解压 tar 包、支持网络资源(功能冗余,优先用COPY+RUN替代)
- VOLUME 指定容器持久化数据卷,绕过联合文件系统,实现数据持久化 / 容器间数据共享,目录修改不影响镜像
- LABEL 为镜像添加元数据(如维护者、版本、描述),替代MAINTAINER(已废弃),支持多标签换行 ()
- USER 指定容器运行 / 后续指令执行的用户 / UID,非必须但提升安全性,避免 root 权限,可通过docker run -u覆盖
- ARG 构建镜像时的临时变量,仅在构建阶段生效,可设置默认值,容器运行时不可用(区别于ENV)
- 指令经典组合
- ENTRYPOINT + CMD:实现 “固定启动命令 + 可替换参数”
- ENTRYPOINT ["java", "-jar"] # 固定核心命令,不可覆盖
- CMD ["app.jar"] # 可替换参数,docker run时可指定其他jar包
- ENV TZ=Asia/Shanghai #统一设置时区,用于解决容器时区和宿主机不一致问题
- 简单例子:
- FROM 192.168.5.24:5000/nginx
- MAINTAINER "zjx"
- COPY index.html /usr/share/ngxin/html/index.html
镜像构建核心命令
- 构建镜像
- docker build -f 【Dockerfile路径】 -t 【镜像名:版本号】 【构建上下文】
- # 示例:使用当前目录的Dockerfile,构建镜像名为myapp、版本v1.0
- docker build -f Dockerfile -t myapp:v1.0 .
- -f:指定 Dockerfile 文件(默认当前目录的 Dockerfile,可省略);
- -t:给镜像打标签(name:tag),tag 建议用版本号(如 v1.0),而非 latest;
- 构建上下文:.代表当前目录,宿主机的文件仅能复制上下文内的内容
- 查看镜像构建分层
- docker history 【镜像ID/镜像名:版本】
- 可查看镜像每一层的构建指令、大小、创建时间,用于排查镜像过大问题
- 验证镜像 / 容器
- docker images # 查看本地已构建镜像
- docker run -d -p 主机端口:容器端口 镜像名:版本 # 基于新镜像启动容器,验证服务
镜像优化原则
- 基础镜像选极简:优先用alpine(几 MB),替代 ubuntu/debian,减少镜像体积
- 合并 RUN 命令:用&&连接多个命令,末尾清理缓存(如rm -rf /var/lib/apt/lists/*),减少分层
- 优先用 COPY 而非 ADD:ADD 功能冗余,仅在需要解压 tar 包时使用,否则用 COPY 更简洁
- 合理设置 WORKDIR:避免使用RUN cd /xxx && xxx,直接用 WORKDIR 指定,路径更清晰
- 非必要不使用 root 用户:通过RUN useradd创建普通用户,再用USER切换,提升容器安全性
Docker 镜像持久化
- 镜像本身的持久化:分层存储
- 镜像由多层只读层(Layer) 叠加而成,每层仅存储与上一层的差异数据(增量更新),所有层最终通过联合文件系统(UnionFS)合并为统一文件系统
- 容器启动时会在只读镜像层之上创建可写层,对文件的修改仅发生在可写层(原镜像层不变)
- 不同镜像可共享相同的只读层(如多个镜像共用 CentOS 基础层),构建镜像时未修改的指令层会复用缓存,加速构建
- 方式 核心原理 适用场景
- 数据卷(Volume) Docker 管理的宿主机目录(/var/lib/docker/volumes/),与容器解耦 持久化应用数据(如数据库)
- 绑定挂载(Bind) 宿主机任意目录直接映射到容器内 开发调试(本地代码同步容器)
- tmpfs 挂载 数据仅存于内存,容器销毁即丢失 临时缓存、敏感数据
- 创建并挂载数据卷(推荐)
- docker volume create nginx-data
- docker run -d -v nginx-data:/usr/share/nginx/html nginx # 卷挂载到容器目录
- 绑定挂载(宿主机目录映射)
- docker run -d -v 宿主机目录:容器目录 nginx
- 验证持久化:删除容器后,数据卷/宿主机目录数据仍存在
- docker rm -f 容器ID
- docker run -d -v nginx-data:/usr/share/nginx/html nginx # 重启容器仍能读取原有数据
- 镜像本身通过分层只读存储 + 写时复制实现轻量化和层复用,容器可写层不持久;
- 容器数据持久化核心依赖数据卷 / 绑定挂载,脱离容器生命周期独立存储;
- 镜像迁移持久化可通过 save/load 导出 / 导入 tar 包实现
镜像发布
- 登录镜像仓库
- docker login -u 【用户名】 -p 【密码】 【仓库地址(私有仓库需指定)】 # 示例:登录Docker Hub
- docker login -u myname -p 123456 # 示例:登录局域网私有仓库
- docker login -u admin -p 123456 192.168.5.24:5000
- 推送镜像
- docker push 【仓库地址/】镜像名:版本
- docker push myname/myapp:v1.0 # 示例:推送到Docker Hub
- docker push 192.168.5.24:5000/myapp:v1.0 # 示例:推送到局域网私有仓库
- 推送私有仓库时,镜像名需包含仓库地址 + 端口,否则会默认推送到 Docker Hub
- 构建 + 运行 + 推送完整流程
- docker build -t 192.168.5.24:5000/my-springboot:v1.0 . # 构建
- docker run -d -p 8080:8080 --name springboot-app 192.168.5.24:5000/my-springboot:v1.0 # 运行
- docker login -u admin -p 123456 192.168.5.24:5000 # 推送私有仓库
- docker push 192.168.5.24:5000/my-springboot:v1.0
Docker 镜像仓库
镜像仓库
镜像仓库
- 定义:用于集中存储、分发、管理 Docker 镜像的服务程序,是镜像的远程存储中心,解决镜像跨主机复用、版本统一管理的问题
- 分类
- 私有仓库:部署在局域网 / 私有网络内,仅内部可访问,数据安全、传输速度快,主流实现为Registry(轻量无界面)和Harbor(企业级带 Web 界面)
- 公有仓库:外网开放访问,无需自建,如 Docker Hub 官方仓库、阿里云容器镜像服务,适合公开镜像的拉取 / 推送
- 核心作用:局域网内提升镜像上传 / 下载速度,实现企业 / 团队内部镜像的统一管理和分发,避免重复构建镜像
轻量私有仓库(Registry)—— 官方轻量版,无 Web 界面
- Docker 官方提供的镜像仓库镜像,仅实现镜像存储和分发核心功能,部署简单、资源占用低,适合个人 / 小型团队局域网使用
- 完整部署步骤(服务端)
- docker pull registry # 拉取Registry官方镜像
- mkdir /share/dockerimg # 创建本地目录,用于仓库数据持久化(避免容器销毁镜像丢失)
- docker run -d -p 5000:5000 --restart=always -v /share/dockerimg:/var/lib/registry registry:latest # 启动Registry容器,-p 5000:5000:映射仓库默认端口;--restart=always:容器意外停止自动重启;-v:本地目录挂载到仓库数据目录
- curl http://仓库IP:5000/v2/_catalog # 验证仓库可用性,返回空仓库标识即正常,正常输出:{"repositories":[]}
- cat > /etc/docker/daemon.json <<EOF # 配置Docker识别私有仓库(解决HTTP访问限制)
- {
- "insecure-registries": ["http://仓库IP:5000"] # 添加私有仓库地址,允许HTTP访问
- }
- EOF
- systemctl daemon-reload && systemctl restart docker # 重启Docker使配置生效
- 镜像推送(服务端)
- 打标签是推送前提,标签必须包含仓库 IP + 端口,否则默认指向 Docker Hub 官方仓库,推送失败
- docker tag nginx 192.168.136.134:5000/nginx:v1 # 格式:docker tag 本地镜像名[:版本] 仓库IP:5000/镜像名[:版本]
- docker tag centos:7.7.1908 192.168.136.134:5000/centos:v1 # 给centos镜像打私有仓库标签
- docker push 192.168.136.134:5000/nginx:v1 # 推送镜像到私有仓库
- ls /share/dockerimg/docker/registry/v2/repositories/ # 查看仓库内已上传镜像(本地挂载目录)
- 镜像拉取(客户端 / 其他 Docker 主机)
- 所有需要访问私有仓库的主机,必须先配置 daemon.json(/etc/docker/daemon.json)
- vim /etc/docker/daemon.json # 配置私有仓库地址,步骤同服务端
- {
- "insecure-registries": ["http://仓库IP:5000"]
- }
- systemctl daemon-reload && systemctl restart docker # 重启Docker
- docker pull 192.168.136.134:5000/nginx:v1 # 拉取镜像
企业级私有仓库(Harbor)—— 带 Web 界面,功能丰富
- VMware 公司开源的企业级镜像仓库,基于 Registry 扩展,提供可视化 Web 管理界面、权限控制、镜像分类等功能
- 支持中文,适合企业 / 大型团队使用,需通过docker-compose启动
- Harbor 完整安装步骤
- tar zxvf harbor-offline-installer-v2.0.3.tgz && cd harbor/ # 解压Harbor离线安装包并进入目录
- cp harbor.yml.tmpl harbor.yml # 复制配置模板,生成自定义配置文件(账户/密码/地址均在此配置)
- vim harbor.yml # 修改核心配置(关键)
- # 需修改内容:hostname: 192.168.136.143 改为Harbor服务器的IP地址;注释掉HTTPS代码块(未配置证书时,仅用HTTP访问)
- docker load -i harbor.v2.10.2.tar.gz #导入镜像
- ./prepare # 初始化Harbor环境(若镜像未提前下载,需先docker load -i 导入Harbor镜像包)
- ./install.sh # 执行一键安装脚本
- docker ps # 验证安装:查看启动的容器,Harbor由多个容器组合而成
- Harbor 基本操作
- docker-compose start # 启动Harbor(在harbor解压目录执行)
- docker-compose stop # 停止Harbor(在harbor解压目录执行)
- Web 界面访问
- 直接在浏览器输入http://Harbor服务器IP,默认管理员账号admin,默认密码可在harbor.yml中查看 / 修改
- 镜像推送(服务端 / 客户端)
- vim /etc/docker/daemon.json # 配置Harbor地址(解决HTTP访问限制)
- {
- "insecure-registries": ["http://HarborIP"]
- }
- systemctl daemon-reload && systemctl restart docker # 重启Docker使配置生效
- docker tag centos:7.7.1908 192.168.136.134/library/centos:v1 # 给本地镜像打标签,格式:HarborIP/项目名/镜像名[:版本](library为默认项目)
- docker login http://192.168.136.134 # 登录Harbor(输入Web界面的账号/密码)
- docker push 192.168.136.134/library/centos:v1 # 推送镜像
- 镜像拉取(客户端 / 其他 Docker 主机)
- # 同推送步骤,先配置daemon.json并重启Docker(命令同前)
- docker pull 192.168.136.134/library/centos:v1 # 直接拉取(公共项目无需登录,私有项目需先docker login)
公有仓库与镜像加速服务
- 阿里云镜像加速器
- 解决从 Docker Hub 官方仓库拉取镜像速度慢的问题,通过配置国内镜像源,提升拉取速度
- 配置步骤
- mkdir -p /etc/docker # 创建daemon.json文件(无则新建)
- sudo tee /etc/docker/daemon.json <<-'EOF' # 写入加速器地址(从阿里云容器镜像服务控制台获取专属地址)
- {
- "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"] # 替换为自己的加速器地址
- }
- EOF
- systemctl daemon-reload && systemctl restart docker # 重启Docker使配置生效
- 公有仓库使用
- Docker Hub 官方仓库(hub.docker.com):Docker 默认的公有仓库,包含海量官方 / 社区镜像,需注册账号后使用
- docker login # 登录Docker Hub(命令行输入,按提示输账号密码),默认登录地址为hub.docker.com
- docker tag centos:7.7.1908 用户名/centos:7.7.1908 # 给镜像打标签,格式:Docker Hub用户名/镜像名[:版本]
- docker push 用户名/centos:7.7.1908 # 推送镜像到个人仓库
- docker pull 用户名/centos:7.7.1908 # 拉取镜像(无需登录,公共镜像可直接拉取)
- 阿里云容器镜像服务
- 国内主流公有仓库,兼具镜像加速和私有 / 公有镜像存储功能,操作流程与 Docker Hub 类似,需在阿里云官网开通 “容器镜像服务” 后,按控制台向导操作
镜像仓库核心操作规范
- 标签(tag)核心规则
- 打标签是镜像推送至仓库的必要前提,标签必须包含仓库地址(IP / 域名 + 端口),否则默认指向 Docker Hub;
- 同一镜像可打多个标签,对应不同仓库 / 版本,仅为镜像 “别名”,不重复占用存储;
- 格式规范:docker tag 本地镜像 仓库地址/项目名/镜像名[:版本](Registry 可省略项目名,Harbor 必须指定项目名,library 为默认项目)
- HTTP 访问限制:Docker 默认要求仓库使用 HTTPS,所有私有仓库(Registry/Harbor)的访问主机,必须在 daemon.json 中配置 insecure-registries,否则推送 / 拉取报错
- 网络连通性:确保客户端与仓库服务器网络互通,关闭防火墙或开放对应端口(Registry 默认 5000,Harbor 默认 80)
- 数据持久化:Registry 需通过-v挂载本地目录,Harbor 的镜像 / 配置数据也会自动挂载到本地,定期备份挂载目录,避免容器销毁导致镜像丢失
- Harbor 认证:推送 Harbor 私有项目的镜像时,必须先执行docker login认证,公共项目可免登录
- 核心命令汇总
- 操作场景 核心命令
- Registry 部署 docker run -d -p 5000:5000 --restart=always -v 本地目录:/var/lib/registry registry # 单容器启动 Registry,挂载本地目录持久化数据
- 镜像打标签 docker tag 本地镜像[:版本] 仓库地址/镜像名[:版本] # 为镜像添加仓库可识别的标签
- 镜像推送 docker push 仓库地址/镜像名[:版本] # 将镜像推送至指定仓库
- 镜像拉取 docker pull 仓库地址/镜像名[:版本] # 从指定仓库拉取镜像
- Harbor 服务管理 docker-compose start/stop # 启动 / 停止 Harbor(在 harbor 目录执行)
- 仓库登录 docker login 仓库地址 # 登录私有仓库(Harbor/Docker Hub / 阿里云)
- 仓库可用性验证 curl http://仓库IP:端口/v2/_catalog # 验证 Registry 仓库是否正常运行
Registry 与 Harbor 对比
- 特性 Registry(轻量版) Harbor(企业版)
- Web 管理界面 无 有(可视化中文)
- 核心功能 仅镜像存储 / 分发 存储分发 + 权限控制 + 镜像分类 + 项目管理
- 部署依赖 无,单容器启动 需安装 docker-compose,多容器组合
- 认证机制 无 支持账号密码登录,区分公共 / 私有项目
- 适用场景 个人 / 小型团队局域网 企业 / 大型团队内部镜像管理
- 资源占用 低 中等
docker资源管理
资源管理
资源管理
- Docker 基于Cgroups(控制组)实现容器的资源配额管理,核心管控 CPU、内存、磁盘 I/O 三大硬件资源,
- 同时提供容器重启策略保障运行健壮性,解决多容器运行时的资源抢占问题,实现资源精细化分配
容器启动管理
- 通过--restart参数设置容器重启策略,实现容器自愈能力,避免容器异常退出或 Docker 守护进程重启后容器无法正常运行
- 策略 核心作用 适用场景
- no Docker 守护进程启动 / 重启时,不自动重启容器(默认策略) 临时测试的容器,无需持久运行
- on-failure[:max-retries] 仅当容器以非零状态异常退出时重启;可指定最大重试次数,超出则放弃 业务容器,正常退出无需重启,异常退出需恢复
- always 无论容器退出状态如何,容器退出即重启;Docker 守护进程启动时也会启动容器 核心服务容器,需持续运行(如数据库、中间件)
- unless-stopped 容器退出时总是重启;但Docker 守护进程启动前已手动停止的容器,不会随守护进程启动 需持久运行,但允许手动停止后不自动恢复的容器
- docker run -it --name c1 --restart=no centos:7.7.1908 /bin/bash # 创建容器指定默认策略
- docker run -it --name c2 --restart=on-failure:3 centos:7.7.1908 /bin/bash # 异常退出重启,最多重试3次
- docker run -it --name c3 --restart=always centos:7.7.1908 /bin/bash # 始终重启策略
- docker run -it --name c4 --restart=unless-stopped centos:7.7.1908 /bin/bash # 除非手动停止,否则始终重启
- docker update --restart=always c1 # 更新运行中容器的重启策略(支持容器名/ID)
- docker inspect c2 # 查看容器重启策略配置(配置信息在42行左右)
- systemctl restart docker # 重启Docker守护进程,验证容器重启策略
- docker rm $(docker ps -aq) # 批量删除所有容器(测试后清理)
- 容器手动执行exit正常退出,on-failure策略不会触发重启;
- always策略下,即使手动docker stop容器,重启 Docker 守护进程后容器仍会自动启动;
- unless-stopped策略是always的轻量版,兼顾 “持久运行” 和 “手动管控
资源管理之 CPU 控制
- 通过指定 CPU 核心、设置 CPU 权重实现 CPU 资源管控,核心解决多容器 CPU 抢占问题,基于 Cgroups 的 CPU 子系统实现
- 核心管控方式
- CPU 权重(--cpu-shares)
- 作用:设置容器调用 CPU 的权重配比,决定容器获取 CPU 时间片的优先级;
- 默认值:1024,权重值无上限,仅为相对比例;
- 生效条件:多个容器在同一 CPU 核心满负荷运行时,权重效果才会体现;单个容器设置权重无意义;
- 示例:容器 A 权重 512、容器 B 权重 1024,满负荷时 A 占用约 33.3% CPU,B 占用约 66.6%;若 A 低负载,B 可占用更多 CPU 资源
- 指定 CPU 核心(--cpuset-cpus)
- 作用:限制容器仅能在指定的 CPU 核心上运行,实现 CPU 核心独占,避免跨核心调度的性能损耗;
- 格式:0(单核心)、0,1(多核心)、0-2(连续核心)
- docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 512 centos:7.7.1908 /bin/bash # 创建容器,指定CPU0/1核心,设置CPU权重512,后台运行
- docker run -itd --name docker20 --cpuset-cpus 0,1 --cpu-shares 1024 centos:7.7.1908 /bin/bash # 创建容器,同核心运行,权重1024(2倍于docker10)
- docker attach docker10 # 进入容器,查看已分配的CPU核心
- cat /sys/fs/cgroup/cpuset/cpuset.cpus # 输出0-1,验证核心限制
- # 进入容器,查看CPU权重配置
- cat /sys/fs/cgroup/cpu/cpu.shares # 输出512,验证权重设置
- yum -y install epel-release && yum -y install stress # 容器内安装stress,压测CPU(2个进程,运行120秒)
- stress -c 2 -v --timeout 120s # 更新运行中容器的CPU权重
- docker update docker20 --cpu-shares 2048 # 宿主机top命令,观察两个容器的CPU占用比例,验证权重效果
资源管理之内存控制
- 通过-m/--memory参数限制容器最大可用内存,为硬性配额,超出限制时容器会被 OOM(内存溢出)杀手终止,避免单个容器耗尽宿主机内存,基于 Cgroups 的内存子系统实现
- 核心参数
- 参数:-m/--memory,支持单位b/k/m/g(字节 / 千字节 / 兆字节 / 吉字节)
- 本质:设置容器内存使用上限,对应 Cgroups 的memory.limit_in_bytes配置
- 生效规则:硬性限制,容器内存使用超出阈值时,会被系统强制终止,保障宿主机内存安全
- # 限制容器最大可用内存 512M(单位支持 b/k/m/g,必须小写)
- docker run -itd --name mem-test -m 512m centos:7 /bin/bash
- # 限制内存 1G + 交换分区 2G(swap 需主机开启交换分区)
- docker run -itd --name mem-test2 -m 1g --memory-swap 3g centos:7 /bin/bash
- # 验证:查看容器内存限制(输出 536870912 字节,即 512M)
- docker exec mem-test cat /sys/fs/cgroup/memory/memory.limit_in_bytes
- 若容器尝试使用超过-m限制的内存,会被 Docker 强制限制,避免主机内存溢出
Docker 容器网络
概念
概念
- Docker 网络的核心是通过 Namespace 实现网络隔离,借助veth pair(虚拟网线)、docker0网桥、iptables+NAT实现容器与主机、
- 容器之间、容器与外网的通信,默认提供 4 种网络模式,同时支持自定义网络和跨主机通信
4 种默认网络模式
- bridge 桥接模式
- 核心原理:Docker 启动后自动创建docker0虚拟网桥(默认网段172.17.0.0/16,网关172.17.0.1),所有容器默认连接到该
- 网桥;容器通过veth pair虚拟网线与网桥相连,宿主机通过iptables的 SNAT 规则做地址转换,实现容器访问外网
- 核心特性:容器有独立 IP、网络隔离性强、需通过-p做端口映射实现外网访问容器、多容器间可通过 IP 互通
- docker run -it --network bridge centos:7.7.1908 /bin/bash # 启动容器指定bridge模式(默认可省略--network bridge)
- ip a | grep docker0 # 查看docker0网桥信息
- docker network inspect bridge # 查看bridge网络详细配置(含容器IP、veth配对信息)
- 容器访问外网流程:容器发包 → veth pair传至docker0 → 宿主机 NAT 将容器私有 IP 转为宿主机公网 IP → 外网响应 → NAT 反向解析回容器 IP
- host 主机模式
- 核心原理:容器跳过docker0网桥,直接共享宿主机的网络命名空间,使用宿主机的 IP、端口、路由表,无 NAT 转换开销
- 核心特性:无独立 IP、无需端口映射(容器端口直接暴露)、网络性能最优;缺点:多容器易端口冲突、隔离性差
- docker run -it --network host centos:7.7.1908 /bin/bash # 启动容器指定host模式
- 适用场景:对网络性能要求高的服务(如 Prometheus、Nginx 反向代理)、无需网络隔离的系统服务
- container 容器模式
- 核心原理:新容器不创建独立网卡,直接共享指定容器的网络命名空间(IP、端口、网卡完全一致),仅网络共享,文件系统、进程仍隔离
- 核心特性:多容器共用一个 IP / 端口、无需端口映射;缺点:主容器停止则附属容器网络失效
- docker run -it --name c1 centos:7.7.1908 /bin/bash # 先启动主容器c1
- docker run -it --name c2 --network container:c1 centos:7.7.1908 /bin/bash # 启动c2共享c1的网络
- 适用场景:Docker sidecar 侧车模式(如主容器加日志收集 / 监控容器)、需多进程共享网络的场景
- none 无网络模式
- 核心原理:容器仅保留lo回环网卡,无任何虚拟 / 物理网卡,无法与外网、宿主机、其他容器通信
- docker run -it --network none centos:7.7.1908 /bin/bash # 启动容器指定none模式
- 适用场景:无需网络的离线任务(如本地数据计算)、极端安全要求的容器(防止网络攻击)
- 自定义网络
- 默认bridge网络不支持容器名解析(只能通过 IP 通信,IP 重启后会变),自定义 bridge 网络内置 Docker DNS 服务,支持容器名直接互通,且隔离性更强,是实际应用的首选
- 核心特性:支持容器名 / 服务名解析(无需记 IP)、可创建多个自定义网络实现业务隔离、默认开启网络隔离
- docker network create my_app_net # 创建自定义桥接网络(driver默认bridge)
- docker run -d --name nginx01 --network my_app_net nginx # 启动容器并加入自定义网络
- docker run -d --name redis01 --network my_app_net redis # 启动容器并加入自定义网络
- docker exec -it nginx01 ping redis01 # 容器间通过容器名互通
- docker network connect my_app_net 容器名/ID # 将已运行的容器加入自定义网络
- docker network disconnect my_app_net 容器名/ID # 将容器从网络中断开
- docker network ls # 查看所有网络
- docker network rm my_app_net # 删除自定义网络(需先断开所有容器)
跨主机容器通信
- 解决不同 Docker 主机上的容器无法互通的问题(默认各主机docker0网段相同,无路由转发),核心方案是Overlay 覆盖网络,常用实现工具:Flannel(入门首选)、Calico、Weave、OVS
- Overlay 网络核心原理
- 构建在宿主机物理网络之上的虚拟网络,通过VXLAN 封装将容器数据包封装后在宿主机间传输,解封后交给目标容器,内置 DNS 支持容器名解析
- Flannel 实现跨主机通信
- Flannel 通过etcd存储集群子网、IP 映射信息,为每台 Docker 主机分配专属子网,实现容器跨主机互通,核心配置逻辑
- 所有节点关闭防火墙 / SELinux,修改主机名和/etc/hosts实现节点互通
- 主节点安装etcd+flannel+docker,从节点安装flannel+docker
- 配置etcd数据库,添加集群统一网段(如172.200.0.0/16)
- 所有节点配置 flannel,关联etcd地址,启动 flannel 服务生成flannel0虚拟网卡
- 配置 Docker 与 flannel 结合(修改daemon.json,指定bip和mtu与 flannel 一致),重启 Docker
- 各节点启动容器,自动分配 flannel 网段 IP,实现跨主机互通
docker网络常用排查 / 管理命令
- docker network ls # 查看所有Docker网络
- docker network inspect 网络名/ID # 查看指定网络详情(含容器、网段、网关)
- docker inspect 容器名/ID | grep -A 10 "Networks" # 查看容器的网络归属(含IP、网关)
- iptables -t nat -L -n # 查看宿主机NAT规则(排查端口映射/外网访问问题)
- docker run --rm --net container:容器名 nicolaka/netshoot tcpdump -i eth0 -nn # 容器内抓包(推荐,无需知道宿主机veth名称)
- ip link show | grep veth # 查看宿主机veth配对信息(排查容器网络连接)
容器通信核心规则
- 通信场景 推荐访问方式 注意事项
- 同一自定义网络的容器间 直接用容器名 / 服务名 默认 bridge 网络不支持,必须用自定义网络
- 同一 docker-compose 的服务间 直接用服务名 Compose 自动创建专属网络,内置 DNS 解析
- 容器访问宿主机 用宿主机物理 IP(Linux 可⽤host.docker.internal) 容器内localhost指向自身,非宿主机
- 宿主机访问容器 容器通过-p 宿主机端口:容器端口做映射,宿主机访问localhost:宿主机端口 避免端口冲突
- 外网访问容器 宿主机公网 IP + 映射的宿主机端口 需开放宿主机防火墙对应端口
Docker 数据卷(Volumes)
- 容器默认是一次性的,数据保存在容器层,删除容器则数据丢失;数据卷是 Docker 管理的宿主机目录,
- 独立于容器生命周期,实现数据持久化和容器间数据共享,性能优于容器层,是生产环境首选
- 为什么需要数据卷
- 解决容器数据丢失问题(容器删除,数据卷保留)
- 实现多容器间数据共享(多个容器挂载同一个数据卷)
- 提升数据读写性能(直接读写宿主机文件系统,无镜像层限制)
- 方便宿主机修改数据(无需进入容器,直接操作宿主机数据卷目录)
- 命名卷
- 核心特性:给卷起唯一名称,由 Docker 统一管理,存储路径固定为/var/lib/docker/volumes/卷名/_data;容器删除后卷不会自动删除,数据持久化;方便管理、迁移和备份
- docker volume create my_data # 创建命名卷(如果不创建的话 run的话会自动创建)
- docker run -it -v my_data:/app/data centos:7.7.1908 /bin/bash # 启动容器挂载命名卷(宿主机卷名:容器内路径)
- docker volume inspect my_data # 查看命名卷详情(含存储路径、驱动)
- docker volume ls # 查看所有数据卷
- 绑定挂载(Bind mount)
- 核心特性:直接将宿主机任意目录 / 文件挂载到容器,宿主机和容器双向互通(宿主机修改文件,容器内实时生效);配置灵活,无需 Docker 管理
- 核心缺点:破坏容器封装性,宿主机目录权限配置不当会导致容器无法读写,安全性低于命名卷
- docker run -it -v /opt/host_data:/app/data centos:7.7.1908 /bin/bash # 宿主机绝对路径:容器内路径(推荐绝对路径,避免相对路径坑)
- docker run -it -v /opt/host_data:/app/data:ro centos:7.7.1908 /bin/bash # 挂载为只读(容器无法修改宿主机文件,:ro)
- 匿名卷
- 核心特性:无自定义卷名,Docker 自动生成随机 ID 作为卷名,存储路径为/var/lib/docker/volumes/随机ID/_data;容器删除后卷不会自动删除,但难以识别和管理
- docker run -it -v /app/data centos:7.7.1908 /bin/bash # 仅指定容器内路径,Docker自动创建匿名卷
- 数据卷核心特性
- 生命周期独立:数据卷独立于容器,容器创建 / 启动 / 停止 / 删除不影响数据卷,除非手动删除
- 多容器共享:多个容器可同时挂载同一个数据卷,实现数据互通
- 性能优异:直接读写宿主机文件系统,比写入容器层快,无镜像层大小限制
- 驱动扩展:默认使用local驱动(本地存储),可扩展为 NFS、GlusterFS、Ceph 等分布式存储,适配集群场景
- 不可修改:数据卷的修改不会被纳入 Docker 镜像的构建过程(即docker commit不会包含数据卷内容)
- docker volume create 卷名 # 创建数据卷(命名卷)
- docker run -it -v 卷名:容器内路径 镜像名 # 启动容器挂载命名卷
- docker run -it -v 宿主机路径:容器内路径 镜像名 # 启动容器挂载绑定挂载
- docker run -it -v 容器内路径 镜像名 # 启动容器挂载匿名卷
- docker volume ls # 查看所有数据卷
- docker volume inspect 卷名 # 查看指定数据卷详情(含存储路径、驱动、挂载容器)
- docker volume rm 卷名 # 删除指定数据卷(需先断开所有挂载的容器)
- docker volume prune # 删除所有未使用的闲置数据卷(清理空间,谨慎使用)
- docker inspect 容器名/ID | grep -A 20 "Mounts" # 查看容器的挂载信息(确认数据卷是否挂载成功)
- 多容器共享数据卷
- 实现多个容器操作同一批数据,核心是多个容器挂载同一个命名卷 / 绑定挂载,两种方式
- 方式 1:直接挂载同一个卷
- docker run -itd --name c1 -v my_data:/app/data centos:7.7.1908 /bin/bash # 启动c1挂载my_data卷
- docker run -itd --name c2 -v my_data:/app/data centos:7.7.1908 /bin/bash # 启动c2挂载同一个my_data卷
- docker exec -it c1 touch /app/data/test.txt # c1中创建文件
- docker exec -it c2 ls /app/data/ # c2中可直接访问
- 方式 2:通过--volumes-from继承已有容器的挂载
- docker run -itd --name c3 --volumes-from c1 centos:7.7.1908 /bin/bash # 启动c3,继承c1的所有挂载配置
- Dockerfile 与数据卷
- 可在 Dockerfile 中用VOLUME ["/容器路径"]指定默认挂载目录,启动容器时若未手动指定卷,Docker 会自动创建匿名卷;
- 生产环境不建议在 Dockerfile 中使用 VOLUME:每次启动容器都会生成新的匿名卷,难以管理,建议启动容器时手动指定命名卷 / 绑定挂载
- FROM centos:7.7.1908
- VOLUME ["/var/www/html"] # 默认识别为匿名卷
- EXPOSE 80
- 数据卷避坑点
- 权限问题:容器内进程的用户 ID(如 MySQL 为 999、Redis 为 1001)需与宿主机数据卷目录的权限匹配,否则容器无法读写,需手动赋权
- chown -R 999:999 /opt/mysql_data # 适配MySQL容器
- 绑定挂载路径:推荐使用宿主机绝对路径,使用相对路径易导致挂载失败(Docker 默认识别为命名卷);
- 数据卷删除:删除容器不会自动删除数据卷,需手动执行docker volume rm,闲置数据卷用docker volume prune清理(需确认无重要数据);
- Windows/macOS 兼容:Docker Desktop 的绑定挂载路径需使用系统规范路径(如 Windows 为D:\host_data,macOS 为/Users/xxx/host_data),避免路径分隔符错误
核心总结
- 网络部分
- 日常开发 / 生产优先使用自定义 bridge 网络,替代默认 bridge,支持容器名解析,避免 IP 依赖;
- 单主机多服务部署用docker-compose + 自定义网络,一键管理,服务名互通;
- 性能敏感场景用host 模式,极端安全场景用none 模式,侧车模式用container 模式;
- 多主机 / 集群部署用Overlay 网络,入门选 Flannel,生产高可用选 Calico;
- 网络问题排查优先查docker network inspect、iptables nat规则、容器 IP / 网关。
- 数据卷部分
- 生产环境首选命名卷,兼顾数据持久化和管理性;开发调试首选绑定挂载,支持代码热更新;
- 数据卷核心原则:容器内不存储重要数据,所有重要数据都挂载到数据卷;
- 多容器共享数据用同一个命名卷,避免匿名卷;
- 构建镜像时尽量不使用 VOLUME,启动容器时手动指定卷,提升可管理性
- 综合实操原则
- 容器化部署核心:网络隔离 + 数据持久化,缺一不可
- 离线部署 / 多主机统一部署:自定义镜像 + 数据卷 + 自定义网络,保证服务一致性和数据安全性
- 所有配置尽量固化为脚本 / 配置文件(如 docker-compose.yml),避免手动输命令,减少出错概率
Docker compose
容器编排基础
容器编排基础
- 编排部署的作用
- 实现复杂容器应用架构的互联互通,解决多容器之间的依赖、网络、协作问题
- 大幅减少大量容器手动部署的时间和人力成本,提升部署效率
- 同一网络内支持容器 / 服务名 DNS 解析,不用记 IP,服务间直接用服务名互通,隔离性更强
- 主流容器编排工具对比
- 工具 核心特点 适用场景
- Docker Compose 单主机多容器编排,通过单个 YAML 文件定义服务关系, 开发、测试环境,单主机部署的小型应用
- 单命令启动 / 管理
- Docker Swarm Docker 原生集群管理工具,将多个 Docker 中小型生产环境,对编排功能要求简单、需与 Docker 无缝集成的场景
- Host 组成集群,支持 YAML 编排
- Kubernetes(k8s) 谷歌开源,云原生计算基金会管理, 大型生产环境,复杂分布式应用、容器云平台核心编排
- 功能强大(自动装箱、滚动更新 / 回滚、水平扩展等)
Docker Compose 核心概念
- docker compose 使用yum进行安装就行
- 核心作用
- 通过单个 YAML 格式文件定义多容器应用的服务关系,使用一条命令即可完成所有容器的启动、停止、管理,简化多容器应用部署流程
- 三大核心定义
- 工程(Project):一个独立的目录,包含 Docker Compose 的 YAML 文件和所有相关配置 / 镜像文件
- 服务(Service):定义单个容器的资源配置,包括镜像、网络、端口、依赖、数据卷等
- 容器(Container):服务运行的实际实例,一个服务可启动多个容器
- 容器编排通用步骤
- 创建独立的工程目录
- 编写docker-compose.yaml文件,定义所有服务配置
- 使用docker-compose命令启动 / 管理服务
YAML 文件核心语法
- YAML 是可读性高的序列化数据格式,是 Docker Compose 的核心配置文件格式,语法规则严格
- 基本语法规则
- 大小写敏感
- 用空格缩进表示层级关系(禁止使用 Tab)
- 相同层级元素左对齐即可,缩进空格数无强制要求
- 用#添加注释,注释行不会被解析
- 三大核心数据类型
- 类型 定义方式 示例
- 对象(键值对) key: value,冒号后必须加空格;支持嵌套 web: <br> image: nginx:latest <br> ports: - "80:80"
- 数组(列表) 以-开头表示数组元素,-后加空格 languages: <br> - html <br> - java <br> - Python
- 纯量(单个值) 不可再分的具体数值,支持多类型 字符串:"Hello"/'World';布尔:true/FALSE;整数:123;空值:~;日期:2025-01-01;时间:2025-01-01T10:00:00+08:00
- Docker Compose 常用核心语法
- 语法 作用 示例
- build 指定镜像构建的 Dockerfile 目录(绝对 / 相对路径),自动构建镜像 build: ./web(当前目录下 web 文件夹有 Dockerfile)
- image 指定启动容器的镜像,镜像不存在则自动拉取 image: haproxy:2.0.29-alpine
- environment 设置容器环境变量,两种写法均可 写法 1:RACK_ENV: development;写法 2:RACK_ENV=development
- expose 暴露容器端口,仅对关联服务可见,不映射到主机 expose: - "80"
- ports 主机与容器的端口映射,主机端口:容器端口 ports: - "80:80"
- restart 容器重启策略 always(始终重启)/on-failure(失败时重启)/unless-stopped(除非手动停止)/no(不重启)
- volumes 数据卷挂载,实现主机与容器数据持久化 / 共享 容器内路径:- /var/lib/mysql;主机:容器:- /opt/data:/var/lib/mysql;只读:- /opt/data:/var/lib/mysql:ro
- links 链接到其他服务的容器,实现容器间网络互通 links: - weba - webb
- depends_on 定义服务启动依赖,保证先启动依赖服务 depends_on: - mysql - redis
- container_name 自定义容器名称,避免自动生成随机名称 container_name: "nginx"
- version 指定 Docker Compose 的版本,需与 Docker 版本兼容 version: '3'(主流常用版本)
- command 覆盖容器默认启动命令 command: nginx -v
- entrypoint 定义容器的"入口程序",当你需要完全替换入口程序时,才需要用 entrypoint,通常和 command 配合使用
- entrypoint: ["bash"] # 覆盖入口点为bash
- command: ["-c", "echo '容器启动成功' && sleep 3600"] # 传给bash的参数:执行echo命令
Docker Compose 常用命令
- 命令 作用
- docker-compose up 启动所有服务,前台运行;加-d为后台运行
- docker-compose down 停止并删除所有容器、网络(数据卷 / 镜像保留)
- docker-compose start 启动已创建的服务容器
- docker-compose stop 停止运行的服务容器(不删除)
- docker-compose ps 查看当前工程的所有容器状态
- docker-compose config 验证docker-compose.yaml文件语法是否正确
- docker-compose exec 服务名/容器ID 命令 进入指定容器执行命令,如docker-compose exec mysql /bin/bash
- docker-compose images 查看当前工程使用的所有镜像
- docker-compose pause 服务名 暂停指定服务的容器
- docker-compose unpause 服务名 恢复暂停的容器
- docker-compose logs 服务名 查看指定服务的日志,加-f实时查看
关键注意事项
- YAML 文件语法严格,冒号后必须加空格、禁止用 Tab 缩进,语法错误会导致容器启动失败
- depends_on仅保证服务启动顺序,不保证依赖服务完全就绪(如 MySQL 启动后需等待初始化完成,否则 PHP 连接会失败)
- expose与ports的区别:expose仅容器间可见,ports映射到主机,外部可访问
- 数据卷挂载建议使用主机绝对路径,避免相对路径导致的挂载失败
- Docker Compose 默认创建专属网络,所有服务容器在同一网络内,可通过服务名互相访问(无需 IP)
- 启动服务时加-d(后台运行),避免终端关闭导致容器停止
k8s
K8s 核心概述
K8s 核心概述
- K8s 是 Google 开源的容器编排平台,用于自动化部署、扩缩容、管理容器化应用。
- 最小调度单位:Pod(一个 Pod 可包含一个 / 多个容器)。
- 架构:Master/Node(主从) 模式。通常是奇数,防止选举平票的情况出现。
- 核心价值:自愈、服务发现、负载均衡、滚动更新、回滚、配置管理。
kubeadm /kubelet/kubectl 核心区别
- kubeadm:集群部署工具
- 用来快速初始化 K8s 集群、加入节点、重置集群,只负责搭建。
- kubelet:节点守护进程
- 每台集群节点必跑的服务,K8s 的「工地管理员」,负责管控本机容器。
- kubectl:集群命令行客户端
- 运维 / 开发操作集群的命令工具,发指令管理资源。
Master 节点组件(控制平面)
- kube-apiserver:集群入口,提供 REST API,负责认证、授权、访问控制,所有组件都和它通信。
- etcd:分布式键值存储,保存集群所有配置与状态数据(相当于数据库)。
- kube-scheduler:调度器,负责把 Pod 调度到合适的 Node 节点。
- kube-controller-manager:控制器管理器,保证实际状态 = 期望状态(副本、节点、服务等)。
Node 节点组件(工作节点)
- kubelet:节点代理,管理本节点 Pod 生命周期、健康检查、上报状态。
- kube-proxy:维护网络规则,实现 Service 负载均衡与服务发现(iptables/ipvs)。
- 容器运行时:负责运行容器,管理容器生命周期:containerd(主流)、Docker、CRI-O。
核心资源对象
- Pod:最小部署单元,共享网络和存储。
- Deployment:无状态应用部署,支持滚动更新、回滚、副本控制。
- StatefulSet:有状态应用(有序、唯一网络、稳定存储)。
- DaemonSet:每个 Node 只运行一个 Pod。
- Service:为一组 Pod 提供固定访问入口与负载均衡。
- ConfigMap/Secret:配置与敏感信息管理。
- Namespace:集群资源隔离。
- Label/Selector:标签选择器,用于筛选资源。
k8s集群部署核心步骤
- 所有节点统一配置
- 修改虚拟机名字
- hostnamectl set-hostname master
- hostnamectl set-hostname node1
- hostnamectl set-hostname node2
- 修改yum仓库
- cat>/etc/yum.repos.d/CentOS-Media.repo <<EOF
- [c7-media]
- name=local
- baseurl=ftp://192.168.5.24/linux_soft/
- gpgcheck=0
- enabled=1
- EOF
- 关闭防火墙
- systemctl stop firewalld
- systemctl disable firewalld
- 关闭 SELinux
- setenforce 0
- sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
- 关闭 Swap 分区(k8s 强制要求)
- swapoff -a
- sed -i '/swap/s/^/#/' /etc/fstab
- 配置主机名映射(所有节点互相解析)
- cat >> /etc/hosts << EOF
- 192.168.247.55 k8s-master
- 192.168.247.56 k8s-node1
- 192.168.247.57 k8s-node2
- EOF
- 安装iptables-services服务,并保存为空规则
- yum install iptables-services -y
- systemctl enable --now iptables.service
- iptables -F -t filter
- iptables -F -t nat
- iptables -F -t mangle
- iptables -F -t raw
- service iptables save
- 加载内核模块 + 开启网络转发
- modprobe br_netfilter
- echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf
- cat > /etc/sysctl.d/k8s.conf << EOF
- net.bridge.bridge-nf-call-iptables = 1
- net.bridge.bridge-nf-call-ip6tables = 1
- net.ipv4.ip_forward = 1
- EOF
- modprobe br_netfilter
- sysctl -p /etc/sysctl.d/k8s.conf
- sysctl --system
- 设置kube-proxy开启ipvs的前置条件
- cat >/etc/sysconfig/modules/ipvs.modules <<EOF
- modprobe ip_vs
- modprobe ip_vs_rr
- modprobe ip_vs_wrr
- modprobe ip_vs_sh
- modprobe nf_conntrack_ipv4
- EOF
- sh /etc/sysconfig/modules/ipvs.modules
- 安装容器运行时(containerd)及Kubernertes组件
- yum install -y containerd.io
- mkdir -p /etc/containerd
- containerd config default > /etc/containerd/config.toml
- sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
- systemctl enable containerd --now
- 安装kubeadm kubectl kubelet
- yum -y install kubeadm kubectl kubelet
- 配置私有仓库
- sed -i 's/registry.k8s.io/192.168.5.24:5000/' /etc/containerd/config.toml
- vim /etc/containerd/config.toml
- [plugins."io.containerd.grpc.v1.cri".registry.configs]#在下面加入
- [plugins."io.containerd.grpc.v1.cri".registry.configs."192.168.5.24:5000".tls]
- insecure_skip_verify = true
- ca_file = ""
- cert_file = ""
- key_file = ""
- [plugins."io.containerd.grpc.v1.cri".registry.mirrors]#在下面加入
- [plugins."io.containerd.grpc.v1.cri".registry.mirrors."192.168.5.24:5000"]
- endpoint = ["http://192.168.5.24:5000"]
- systemctl restart containerd
- Master修改
- 修改配置文件
- vim kubeadm-config.yaml
- apiVersion: kubeadm.k8s.io/v1beta3
- kind: InitConfiguration
- nodeRegistration:
- criSocket: unix:///var/run/containerd/containerd.sock
- kubeletExtraArgs:
- cgroup-driver: "systemd"
- apiVersion: kubeadm.k8s.io/v1beta3
- kind: ClusterConfiguration
- imageRepository: "192.168.5.24:5000"
- kubernetesVersion: "v1.28.15"
- networking:
- podSubnet: "10.244.0.0/16"
- serviceSubnet: "10.96.0.0/12"
- dnsDomain: "cluster.local"
- apiServer:
- extraArgs:
- advertise-address: "192.168.247.55" # 主节点IP
- timeoutForControlPlane: "5m0s"
- controllerManager: {}
- scheduler: {}
- apiVersion: kubelet.config.k8s.io/v1beta1
- kind: KubeletConfiguration
- cgroupDriver: "systemd" # 必须与InitConfiguration中的一致
- 初始化master
- kubeadm init --config=kubeadm-config.yaml --upload-certs --v=5
- mkdir -p $HOME/.kube
- cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
- chown $(id -u):$(id -g) $HOME/.kube/config
- kubectl apply -f kube-flannel.yaml
- 在其他非master节点执行
- mkdir -p $HOME/.kube
- scp root@192.168.247.128:/etc/kubernetes/admin.conf $HOME/.kube/config
- kubectl apply -f kube-flannel.yaml
- 加入master,每次初始化都不一样
- kubeadm join 192.168.247.128:6443 --token 9p8spu.0uz1cvj2vum1py5w \
- --discovery-token-ca-cert-hash sha256:dee4bb1902fc527f60aa95a8e92efbd6e7b998fcb1ba1
- 注意事项
- swap 必须关闭,否则 kubelet 无法启动。
- br_netfilter 模块必须加载,否则网络报错。
- containerd 必须配置 SystemdCgroup = true。
- Master 才能用 kubectl,Node 只需要 join。
- 网络插件必须安装,否则节点 NotReady。
- 防火墙必须关闭,否则 node 连不上 6443。
常用 Kubernetes 命令
- crictl images #查看本地k8s镜像
- ctr -n k8s.io images ls
- docker save 镜像名 | ctr -n k8s.io images import - #导入镜像到本地k8s
- ctr -n k8s.io images import 镜像名
- 导入会出现很多的WARN
- kubectl cp 本地文件路径 Pod名称:Pod内路径 #上传文件到pod里
- 集群 / 节点
- kubectl get no # 查看集群所有节点状态(是否Ready)
- kubectl get cs # 查看集群核心组件健康状态(apiserver/etcd等)
- kubectl top no # 查看节点CPU、内存资源使用率
- kubectl describe node <节点名> # 查看节点详细信息(IP、资源、事件、标签)
- 命名空间
- kubectl get ns # 查看集群所有命名空间
- kubectl create ns <名称> # 创建新的命名空间(用于隔离环境:dev/test/prod)
- Pod 相关
- kubectl get pods # 查看当前命名空间下的所有Pod
- kubectl get pods -A # 查看集群所有命名空间下的Pod(最常用)
- kubectl describe pod <pod名> # 查看Pod详细信息(用于排查启动失败、网络问题)
- kubectl logs <pod名> # 查看Pod日志(排查应用报错)
- kubectl exec -it <pod名> -- /bin/bash # 进入Pod容器内部(执行命令、查看文件)
- kubectl delete pod <pod名> # 删除指定Pod(K8s会自动重建,除非是裸Pod)
- Deployment 管理
- kubectl create deploy nginx --image=nginx # 创建名为nginx的Deployment,使用nginx镜像
- kubectl get deploy # 查看所有Deployment(副本数、状态)
- kubectl scale deploy nginx --replicas=3 # 扩容/缩容:将nginx副本数改为3个
- kubectl set image deploy nginx nginx=nginx:1.23 # 滚动更新镜像版本(不停机升级)
- kubectl rollout history deploy nginx # 查看Deployment更新历史记录
- kubectl rollout undo deploy nginx # 回滚到上一个版本(更新失败时使用)
- Service 管理
- kubectl get svc # 查看集群所有Service(IP、端口、类型)
- kubectl expose deploy nginx --port=80 --type=NodePort # 将Deployment暴露为Service,提供外部访问
- 资源清单操作
- kubectl apply -f xxx.yaml # 通过YAML文件创建/更新资源(推荐方式)
- kubectl delete -f xxx.yaml # 通过YAML文件删除对应资源
- kubectl get <资源> -o yaml > 备份.yaml # 导出资源配置为YAML文件(备份、复用)
- 集群维护
- kubeadm token create --print-join-command # 生成新的节点加入集群命令(token过期时使用)
- kubeadm reset -f # 重置节点(清空K8s配置,重新初始化/加入)
- systemctl restart kubelet # 重启节点kubelet服务(排查节点NotReady)
- 高频实用命令
- kubectl get all -A # 查看所有资源(Pod/Svc/Deploy等),所有命名空间
- kubectl delete deploy <名称> # 删除Deployment
- kubectl delete svc <名称> # 删除Service
- kubectl get endpoints # 查看Service后端绑定的Pod地址
- kubectl api-resources # 查看K8s所有资源类型
k8s pod
Pod
Pod
- K8s 最小调度 / 管理单元
- 一个 Pod = 1 个或多个紧耦合容器
- Pod 是逻辑概念,底层还是 Linux Namespace + Cgroups
- 所有容器共享网络、共享存储、同一个 IP,每个pod都有虚拟IP(随机的)
- 内部靠 Pause 容器实现网络 / 存储共享与进程托管
为什么需要 Pod
- 解决多容器协同:服务依赖、日志收集、代理等必须一起运行
- 统一网络:一个 Pod 一个 IP,容器用 localhost 互通,避免端口冲突
- 统一存储:多个容器可挂载同一个 Volume
- 健康检查 / 自愈 / 扩缩容:裸容器做不到,Pod 可以
- 集群调度:由 K8s 统一调度到节点
Pod 核心特性
- 网络共享
- 同一个 Pod 共用一个 Network Namespace
- 所有容器共用一个 IP
- 端口空间共享(不能同时监听同一个端口)
- 容器间直接用 localhost:端口 访问
- 存储共享
- 可声明 Volume,所有容器都能挂载
- 适合日志、配置、数据共享
- 多容器设计模式
- 主容器:业务服务
- Sidecar 容器:日志、监控、代理、流量治理
- Init 容器:初始化前置任务
Pod 生命周期状态
- 状态 含义
- Pending 已接收,未创建完,正在创建pod
- Running 正常运行中
- Succeeded 全部正常退出
- Failed 有容器异常退出
- Unknown 无法获取状态
- ImagePullBackOff 拉镜像失败 多次拉取失败后
- ErrImagePull 镜像拉取失败 单次拉取失败
- CrashLoopBackOff 反复崩溃重启
- OOMKilled 内存溢出被杀
- Completed 正常执行完毕
- Terminating 正在删除
Pod YAML 核心字段
- apiVersion: v1
- kind: Pod
- metadata:
- name: pod-name
- namespace: default
- labels:
- app: myapp
- spec:
- containers:
- - name: container-name
- image: image:tag
- imagePullPolicy: IfNotPresent
- command: ["sleep"]
- args: ["3600"]
- resources:
- requests:
- cpu: 100m
- memory: 128Mi
- limits:
- cpu: 500m
- memory: 512Mi
- ports:
- - containerPort: 80
- volumeMounts:
- - name: vol
- mountPath: /data
- volumes:
- - name: vol
- emptyDir: {}
- restartPolicy: Always
- nodeSelector:
- key: value
- 关键字段
- imagePullPolicy(镜像拉取策略)
- Always:总是拉取配置文件设定的仓库里的镜像
- IfNotPresent:本地有就用本地,本地没有则拉取仓库
- Never:只用本地
- resources
- requests:最低需要
- limits:上限
- restartPolicy
- Always:一直重启(默认)
- OnFailure:失败才重启
- Never:失败后不重启
- nodeSelector:调度到匹配标签的节点
- command = 容器启动时要执行的 主命令 #相当于你在 Linux 里直接敲命令
- args = 传给 command 的 参数(选项) #相当于在命令行执行:command的命令加上args的参数 例子:sleep 3600
Pod 分类
- 自主 Pod
- 无控制器管理
- 删除后不会重建
- 控制器管理 Pod
- Deployment / StatefulSet / DaemonSet / Job 等管理
- 保证副本数、自愈、滚动更新
- 通过 label + selector 关联
常用命令
- kubectl exec <pod名称> -- <你要执行的命令> #不进入 Pod,直接在外面执行命令
- kubectl cp 本地文件路径 Pod名称:Pod内路径 #上传文件到pod里
- kubectl get pods # 查看所有 Pod(默认 namespace)
- kubectl get pods -o wide # 查看 Pod 详情(含 IP、节点)
- kubectl get pods -A # 查看所有命名空间下的 Pod
- kubectl get pods -n <ns名> # 查看指定命名空间的 Pod
- kubectl get pod <pod名> # 查看单个 Pod 状态
- kubectl get pods --show-labels # 查看 Pod 并显示标签
- kubectl get pods -l app=myapp # 按标签筛选 Pod
- kubectl get pod <pod名> -o yaml # 查看 Pod 的完整 YAML 配置
- kubectl describe pod <pod名> # 查看 Pod 详细信息、事件、错误原因
- kubectl logs <pod名> # 查看 Pod 日志
- kubectl logs -f <pod名> # 实时跟踪 Pod 日志
- kubectl logs <pod名> -c <容器名> # 查看 Pod 中指定容器的日志
- kubectl logs <pod名> -p # 查看 Pod 上一次崩溃的日志
- kubectl exec -it <pod名> -- /bin/bash # 进入 Pod 默认容器
- kubectl exec -it <pod名> -c <容器名> -- sh # 进入 Pod 指定容器
- kubectl exec <pod名> -- ls / # 在 Pod 内直接执行命令
- 只能进入运行中的容器
- kubectl create -f pod.yaml #通过TYAML文件创建pod
- kubectl apply -f pod.yaml # 通过 YAML 文件创建/更新 Pod
- kubectl delete -f pod.yaml # 通过 YAML 文件删除 Pod
- kubectl delete pod <pod名> # 删除指定 Pod
- kubectl delete pod <pod名> --force --grace-period=0 # 强制删除 Pod
- kubectl delete pods --all # 删除当前命名空间所有 Pod(谨慎)
- kubectl label pod <pod名> app=myapp # 给 Pod 添加标签
- kubectl label pod <pod名> app=v2 --overwrite # 修改 Pod 标签
- kubectl label pod <pod名> app- # 删除 Pod 标签
- kubectl get ns # 查看所有命名空间
- kubectl create ns <ns名> # 创建命名空间
- kubectl delete ns <ns名> # 删除命名空间(会清空内部资源)
- kubectl edit <资源类型> <资源名称> #直接编辑 K8s 里正在运行的资源
Namespace(命名空间)
- 作用:逻辑隔离资源
- 进行操作的时候如果不指定命名空间就会使用默认的命名空间,这样就有可能找不到想操作的的对象
- 系统自带
- default:默认
- kube-system:系统组件
- kube-public:公共可读
- kube-node-lease:节点心跳
- 常用命令
- kubectl get ns 查看命名空间
- kubectl create ns myns 创建命名空间
- kubectl delete ns myns 删除命名空间
Pod 调度方式
- 在yml文件里设置
- nodeSelector:按节点标签调度
- nodeName:直接指定节点
- K8s 默认调度器:自动分配最优节点
pod控制器
核心概述
核心概述
- Pod 控制器(Controller)是 K8s 中用于管理 Pod 生命周期的核心组件,通过监控 Pod 状态,
- 实现 Pod 的创建、扩容、缩容、升级、回退、自愈等功能,解决自主式 Pod 易消亡、无管理的问题
- 核心作用:保障 Pod 按预期数量运行,实现业务的高可用和自动化管理
- 管理逻辑:控制器通过标签选择器(Selector) 关联 Pod,仅管理匹配标签的 Pod
Pod 控制器分类及核心功能
- K8s 中 Pod 控制器按业务场景分为 7 类,核心功能和适用场景各有侧重,其中 Deployment、DaemonSet、StatefulSets 为日常使用高频控制器
- 控制器类型 核心功能 适用场景
- ReplicaSet(副本集) 支持基于集合的标签选择器; 为 Deployment 提供底层副本管理,一般不单独使用
- 精准控制 Pod 副本数量,实现扩容 / 缩容
- Pod 自愈(Pod 异常时自动重建)
- Deployment 集成 ReplicaSet 所有功能 无状态应用部署(如静态 Web、微服务无状态节点)
- 支持 Pod滚动升级、版本回退
- 支持上线部署、创建副本、扩缩容
- StatefulSets 管理有状态 Pod, 有状态应用部署(如 MySQL 集群、Elasticsearch、ZK 集群)
- 为 Pod 分配固定标识(名称、网络、存储)
- 支持有序启动 / 停止、扩缩容
- DaemonSet 让集群所有节点(含 Master) 运行同一个 Pod 集群级全局任务(如日志收集(ELK)
- 节点新增时自动调度 Pod,节点移除时自动删除 Pod 监控采集(Prometheus Node Exporter)、网络插件代理)
- Pod 被删除后自动重建
- Jobs 管理一次性任务Pod,任务完成后 Pod 终止,不重启 临时批处理任务(如数据导出、文件解析)
- CronJob 基于时间调度的 Jobs,实现周期性任务执行 定时批处理任务(如定时备份、定时日志清理)
- 关键补充:无状态应用 vs 有状态应用
- 无状态应用(服务):Pod 之间无差别,无固定标识,数据不持久化在本地,可随意扩缩容、调度,如 Nginx、静态 Web 服务
- 有状态应用(服务):Pod 之间有唯一标识,需要固定网络、持久化存储,启动 / 扩缩容有顺序要求,如数据库、中间件集群
补充
- 无状态服务
- 实例无差别、无本地记忆,不存业务 / 会话数据,数据都放独立共享存储(如 Redis/MySQL)
- 随便扩缩容、换实例,处理请求结果一致,K8s 用 Deployment 部署,比如微服务接口、Nginx、网关
- 有状态服务
- 实例有专属身份(固定名 / 存储 / 网络),存持久化状态 / 集群关系,实例间有主从 / 顺序依赖
- 不能随意调度替换;K8s 用 StatefulSets 部署,比如 MySQL/ES/ZK 集群、Redis 主从
- 灰度发布(金丝雀发布)
- 不一次性全量更新版本,先切少量流量 / 部分实例到新版本,验证无问题后,逐步扩大新版本流量占比,最终全量替换;
- 出问题可快速切回旧版本,把故障影响降到最小,K8s 中常基于 Deployment 滚动更新、Service 标签、Ingress 权重实现
- 总结:无状态无记忆可随便换,有状态有身份有依赖;灰度发布是 “小步试错、逐步放量” 的发布方式
Deployment 控制器
- Deployment 是无状态应用的首选控制器,底层通过管理 ReplicaSet 实现 Pod 的副本管理,
- 核心优势是支持滚动升级和版本回退,避免升级过程中业务中断
- K8s Deployment 完整工作流程
- 用户通过 kubectl 提交 Deployment 资源至 API Server,配置存入 etcd 后,Deployment 控制器监测到资源变更,依据标签选择器创建对应ReplicaSet ReplicaSet 依托相同标签匹配规则负责管控 Pod 副本数量并生成 Pod 资源,未绑定节点的 Pod 交由调度器筛选合适节点完成绑定
- 目标节点上kubelet 监听到 Pod 变更后拉取镜像、创建并启动容器,各组件全程依托 API Server 交互、依靠 Label 与 Selector 建立关联
- Deployment 不直接对接 Pod,通过 ReplicaSet 间接管控 Pod 生命周期
- 核心特性
- 集成副本管理、扩容缩容、自愈、滚动升级、版本回退全功能
- 所有管理的 Pod 无差别,运行同一镜像,可调度到任意节点,无启动顺序
- 滚动升级时逐步删除旧 Pod、创建新 Pod,保障业务持续可用
- 记录版本更新历史,支持精准回退到指定版本
- 能够实现无缝滚动升级、自动扩缩容、灾难自愈、一键版本回滚
- 两种创建方式
- 命令行创建(快速测试)
- # 创建名称为deploy1的Deployment,2个副本,镜像为centos-httpd:v1,暴露80端口
- kubectl run deploy1 --image=centos-httpd:v1 --port=80 --replicas=2
- YAML 文件创建(生产推荐,可定制化)
- #核心字段说明 + 示例(apiVersion 可根据 K8s 版本适配apps/v1)
- apiVersion: apps/v1 # 企业生产唯一推荐版本
- kind: Deployment # 资源类型
- metadata:
- name: nginx-deploy # 资源名称
- namespace: default # 命名空间,企业建议按业务划分(如prod/uat/dev)
- labels: # 资源自身标签,用于资源筛选
- app: nginx-deploy
- annotations: # 注解,企业用于记录版本、归属、CI/CD信息,比label更灵活
- deployment.kubernetes.io/revision: "1" # 版本号,自动生成
- business: web # 自定义:业务线标识
- spec: # Deployment核心规格(一级spec)
- replicas: 3 # 副本数,企业建议至少2个(高可用)
- revisionHistoryLimit: 10 # 保留的历史版本数,企业建议5-10(便于回滚,避免占用资源)
- progressDeadlineSeconds: 600 # 滚动更新超时时间,超时则标记更新失败
- selector: # 标签选择器,必须与Pod模板标签一致(核心,否则控制器无法管理Pod)
- matchLabels:
- app: nginx-deploy
- strategy: # 滚动更新策略,企业核心配置,控制更新过程中的可用性
- type: RollingUpdate # 企业唯一推荐(另一种Recreate为删除所有旧Pod再建新Pod,会中断业务)
- rollingUpdate:
- maxSurge: 25% # 最大超配数:更新时可超出副本数的比例/数值,如3副本可最多创建4个Pod
- maxUnavailable: 25% # 最大不可用数:更新时允许不可用的Pod比例/数值,如3副本至少2个可用
- template: # Pod模板(企业所有Pod配置的核心载体)
- metadata:
- labels:
- app: nginx-deploy # 必须与selector.matchLabels一致
- spec: # Pod规格(二级spec)
- containers:
- - name: nginx # 容器名称,唯一
- image: nginx:1.7.9 # 容器镜像,企业建议使用固定版本(避免拉取最新版导致兼容问题)
- imagePullPolicy: IfNotPresent # 镜像拉取策略,企业内网环境首选(节省带宽,加快启动)
- ports:
- - containerPort: 80 # 容器端口
- restartPolicy: Always # 重启策略,企业默认Always(Pod异常自动重启)
- terminationGracePeriodSeconds: 30 # 容器优雅退出时间,企业建议30s(留给容器销毁连接、保存数据)
- 创建命令:
- kubectl create deploy nginx-deploy --image=nginx:1.7.9 --replicas=3 # 方式1:命令行快速创建(测试/临时使用)
- kubectl apply -f nginx-deploy.yaml # 创建设置,更新也用此命令(幂等) # 方式2:YAML文件创建(生产唯一推荐,可版本化管理)
- kubectl create -f nginx-deploy.yaml # 仅创建,已存在则报错(不推荐)
- 核心实操命令
- 查看相关资源
- kubectl get deploy -n 命名空间 # 简洁查看,简写kubectl get deploy
- kubectl get deploy nginx-deploy -o wide -n 命名空间 # 查看详细信息(节点、更新状态)
- kubectl describe deploy nginx-deploy -n 命名空间 # 核心排障命令:查看事件、镜像、RS关联、更新过程
- kubectl rollout status deploy nginx-deploy -n 命名空间 # 查看滚动更新进度(企业更新必看)
- kubectl get pods --show-labels -n 命名空间 # 查看Pod及标签,验证与控制器的匹配关系
- kubectl rollout history deploy nginx-deploy -n 命名空间 # 查看更新历史(版本号、变更原因)
- kubectl rollout history deploy nginx-deploy --revision=2 -n 命名空间 # 查看指定版本详细配置
- kubectl get deploy <你的deployment名字> -o yaml > 最终版本.yaml #导出
- Pod 自愈测试
- 删除 Deployment 管理的 Pod,控制器会自动重建新 Pod,保障副本数符合预期:
- kubectl delete pod <pod名称>
- 版本滚动更新
- 更新本质:创建新的 ReplicaSet,逐步缩容旧 ReplicaSet、扩容新 ReplicaSet,实现无中断升级
- # 更新Deployment的容器镜像,--record记录更新历史(便于回退)
- kubectl set image deployment <deployment名称> <容器名称>=<新镜像> --record
- # 验证更新状态(查看滚动升级进度)
- kubectl rollout status deployment <deployment名称>
- # 验证更新后的镜像
- kubectl describe deployment <deployment名称> | grep -i image
- 更新
- 核心原则:仅当 Pod 模板(.spec.template)修改时,才会触发更新(如镜像、资源、端口)
- # 方式1:修改镜像(最常用,CI/CD流水线核心命令)
- kubectl set image deploy nginx-deploy nginx=nginx:1.9.1 -n 命名空间 --record
- # 方式2:编辑配置文件(临时修改/小调整)
- kubectl edit deploy nginx-deploy -n 命名空间 # 直接修改YAML,保存后自动触发更新
- # 方式3:更新YAML文件(生产推荐,版本化管理)
- kubectl apply -f nginx-deploy.yaml -n 命名空间
- 回滚
- 核心是回滚 Pod 的模板配置(最常用的就是镜像版本,还包括容器配置、环境变量、端口等)
- # 方式1:回滚到上一个稳定版本(故障时最快操作,企业首选)
- kubectl rollout undo deploy nginx-deploy -n 命名空间
- # 方式2:回滚到指定版本(精准回滚,需先查历史版本号)
- kubectl rollout undo deploy nginx-deploy --to-revision=2 -n 命名空间
- #查看回滚记录
- kubectl rollout history 资源 名字
- 扩缩容
- # 方式1:命令行动态调整(快速扩缩容,应对流量波动)
- kubectl scale deploy nginx-deploy --replicas=5 -n 命名空间 # 扩容到5副本
- kubectl scale deploy nginx-deploy --replicas=0 -n 命名空间 # 临时下线(企业维护/发布时使用)
- # 方式2:修改YAML文件(生产推荐,版本化保存副本数配置)
- kubectl apply -f nginx-deploy.yaml -n 命名空间
- 删除
- 删除后,其管理的 ReplicaSet 和 Pod 会被一并删除:
- kubectl delete -f nginx-deploy.yaml -n 命名空间 # 按文件删除
- kubectl delete deploy nginx-deploy -n 命名空间 # 按名称删除
- 滚动更新核心原理
- 更新触发:修改 Pod 模板后,Deployment 会创建新的 ReplicaSet,同时保留旧的 ReplicaSet;
- 更新过程:按maxSurge和maxUnavailable配置,逐步创建新 Pod
- 逐步删除旧 Pod(新 PodRunning 后再删旧 Pod),确保业务持续可用;
- 示例:3 副本,maxSurge=25%、maxUnavailable=25%→最多创建 4 个 Pod
- 至少 2 个可用→新 RS 扩到 1→旧 RS 缩到 2→新 RS 扩到 2→旧 RS 缩到 1→新 RS 扩到 3→旧 RS 缩到 0;
- 版本保留:旧 RS 不会被删除,仅缩容为 0,保留在集群中
- 为版本回滚提供基础(可通过revisionHistoryLimit控制保留数量)
- Deployment/RS/Pod 核心关系
- 层级关系:Deployment(1) → ReplicaSet(N) → Pod(M),即一个 Deployment 可管理多个 RS,一个 RS 管理多个 Pod
- 创建关系:Deployment 首次创建时,生成一个 RS,并由该 RS 创建指定数量的 Pod
- 每次更新 Deployment,会生成新的 RS,新 RS 创建新 Pod,旧 RS 缩容 Pod;
- 命名规则:
- Pod 名称:deploy名称-RS哈希值-随机字符串(如 nginx-deploy-5c6485bbd4-qc4gf);
- RS 哈希值:由 Pod 模板配置生成,Pod 模板不变,哈希值不变;
- 核心避坑:直接修改 / 删除 Deployment 管理的 Pod 无效!控制器会根据 RS 的副本数要求
- 自动重建 Pod,企业中所有 Pod 的修改必须通过 Deployment 实现
- 企业生产最佳实践
- 副本数:至少配置 2 个,实现业务高可用,避免单节点故障导致服务中断
- 镜像版本:使用固定版本(如 nginx:1.7.9),避免使用 latest(拉取最新版,导致版本不一致、兼容问题)
- 更新策略:固定RollingUpdate,maxSurge和maxUnavailable建议设置为 25%-50%(平衡更新速度和业务可用性)
- 历史版本:revisionHistoryLimit设置为 5-10,既便于回滚,又避免保留过多 RS 占用集群资源;
- 命名空间:按业务 / 环境划分(如 prod - 电商、uat - 测试、dev - 开发),实现资源隔离
- 标签规范:统一标签规则(如 app = 服务名、business = 业务线、env = 环境),便于资源筛选和管理
- 临时下线:通过scale --replicas=0实现,比直接删除 Deployment 更灵活(无需重新配置,扩缩容即可恢复)
DaemonSet 控制器
- 企业中集群基础设施部署专属,无业务场景使用,核心用于日志收集(Filebeat/ELK)、监控采集(Prometheus Node Exporter)
- 网络插件(Calico/Flannel),配置简单,无复杂操作
- 核心生产特性
- 集群所有节点(含 Master) 仅运行一个 Pod,Pod 数量 = 集群节点数,无需配置副本数
- Master 节点需配置污点容忍(企业 Master 节点均开启污点,防止普通 Pod 调度),这是必配项
- 节点生命周期联动:节点加入→自动调度 Pod,节点移除→自动删除 Pod,Pod 异常→自动重建(企业基础设施高可用保障)
- YAML 配置(核心保留污点容忍)
- apiVersion: apps/v1 # 企业生产推荐版本
- kind: DaemonSet
- metadata:
- name: filebeat-ds # 按组件命名,企业规范
- namespace: kube-system # 集群组件建议部署在kube-system命名空间
- spec:
- selector:
- matchLabels:
- app: filebeat
- template:
- metadata:
- labels:
- app: filebeat
- spec:
- tolerations: # Master污点容忍,企业必配
- - key: node-role.kubernetes.io/master
- effect: NoSchedule
- containers:
- - name: filebeat
- image: elastic/filebeat:7.17.0 # 固定版本,企业规范
- imagePullPolicy: IfNotPresent
- 常用实操命令
- kubectl get ds -n kube-system # 查看DaemonSet,简写kubectl get ds
- kubectl get pod -o wide -n kube-system # 验证每个节点一个Pod
- kubectl apply -f daemonset.yaml -n kube-system # 创建/更新
- kubectl delete ds filebeat-ds -n kube-system # 删除
其他控制器
- StatefulSets(有状态服务专属)
- 企业用途:仅部署有状态服务(MySQL 集群、Elasticsearch、ZooKeeper、Redis 集群)
- 核心特性:Pod 有固定名称、固定网络、持久化存储,支持有序启动 / 停止 / 扩缩容
- 使用频率:远低于 Deployment,仅 DBA / 中间件运维使用,业务开发无需深入
- CronJob(定时任务专属)
- 企业用途:集群定时任务(数据库定时备份、日志定时清理、数据定时同步)
- 核心特性:基于时间调度(类似 Linux crontab),底层管理 Jobs
- 企业配置:重点控制并发策略(禁止并发 / 允许并发 / 替换并发),避免任务重复执行
- ReplicaSet/Jobs/ReplicationController
- ReplicaSet:Deployment 底层依赖,企业无单独使用场景,无需学习
- Jobs:一次性批处理任务(如数据导出),场景小众,配置简单
- ReplicationController:RS 的旧版本,企业已全面淘汰,完全无需学习
Deployment 与 DaemonSet 核心区别
- 对比维度 Deployment(企业业务核心) DaemonSet(企业基础设施核心)
- 部署范围 集群部分节点(按副本数调度) 集群所有节点(每个节点 1 个 Pod)
- 副本数 手动指定,企业建议≥2(高可用) 无副本数配置,Pod 数 = 节点数
- 核心用途 业务层无状态服务(微服务、Web、接口) 集群基础设施(日志、监控、网络)
- 更新策略 滚动更新(复杂,可配置超配 / 不可用数) 滚动更新(简单,逐节点更新)
- 命名空间 按业务划分(prod/uat/dev) 集群组件专属(kube-system)
- 操作复杂度 高(更新、回滚、扩缩容、排障) 低(仅基础创建 / 查看 / 删除)
- 企业使用人员 所有开发 / 运维(核心技能) 运维 / 架构师(基础设施部署)
通用实操技巧
- 排障核心命令:kubectl describe <资源类型> <资源名称>,查看Events 事件是解决所有创建 / 运行失败的关键
- 资源格式化输出:-o json/yaml/wide,企业排障时常用-o yaml查看完整配置,-o wide查看节点 / Pod IP
- 命名空间指定:企业集群必加-n 命名空间,避免操作默认命名空间导致资源混乱
- 命令补全:企业运维必配kubectl completion bash,开启命令补全,提高操作效率
- 配置版本化:所有 YAML 配置文件纳入 Git 管理(企业 DevOps 核心),实现配置可追溯、可回滚
K8s Service
Service概念
Service概念
- Service = Pod 的固定入口 + 负载均衡 + 自动发现
- Pod IP 会变,但 Service IP 不变
- 自动找带对应标签的 Pod
- 自动做负载均衡(轮询等)
- 解决 “Pod 挂了、重建后 IP 变了,访问就断” 的问题
Service 核心作用
- 提供固定访问地址(ClusterIP / NodePort)
- 自动发现 Pod(通过 label selector)
- 负载均衡(流量分给多个 Pod)
- 防止 Pod 失联(Pod 重建不影响访问)
- 流量转发:底层用 iptables 或 ipvs
- 为一组 Pod 提供固定访问入口,实现负载均衡、Pod 动态发现,屏蔽 Pod IP 变化
Service 为什么必须存在
- Pod IP 会变、会飘、会重建,不能直接用 IP 访问
- Service 提供固定入口、固定域名、固定 IP
- 服务之间只用 Service 名通信,不用 IP
Endpoint(EP)是什么
- Service 匹配到的 Pod IP: 端口列表
- 查看命令:kubectl get ep
- EP 为空 = Service 没找到 Pod = 标签不对
Service 流量完整路径
- 外部访问 → NodeIP:NodePort → Service → Endpoint → Pod
- 流量走 Node 节点,不走 Master
- kube-proxy 负责转发(iptables/ipvs)
- CNI(flannel/calico)负责 Pod 之间通信
- 三者真实工作流程( Service、Endpoint、Pod)
- Pod 启动,自带 IP 和端口
- EP 自动发现 Pod,把 IP 加入列表
- SVC 拿着 EP 列表做负载均衡
- 用户访问 SVC → SVC 转发给 EP 里的某个 Pod
- Pod 挂了 → EP 自动删掉它 → SVC 不再转发流量
Service 域名访问
- 同命名空间:curl service名
- 跨命名空间:curl service名.命名空间.svc.cluster.local
Service 四种类型
- ClusterIP(默认、最常用)
- 只在集群内部访问
- 分配一个固定虚拟 IP
- 微服务之间互相调用用它
- NodePort(外部访问必须用)
- 在每个节点开一个端口(30000~32767)
- 外部浏览器访问:节点IP:端口
- 企业测试 / 简单外部访问最常用
- LoadBalancer(云厂商用,贵)
- 阿里云 / 腾讯云 / AWS 专用负载均衡器
- 本地 K8s 一般不用
- ExternalName(极少用)
- 把外部服务映射进集群
- 几乎不用
两种负载均衡策略
- RoundRobin(默认):轮询
- SessionAffinity: ClientIP:同一个 IP 永远访问同一个 Pod(类似 ip_hash)
Headless Service(无头服务)
- 没有 ClusterIP
- DNS 直接解析到 Pod IP 列表
- 用于 StatefulSet 有状态服务(如 MySQL、Redis)
ClusterIP
- 作用:集群内部访问,外部不能访问
- 关键端口:port:Service 自己的端口 targetPort:Pod 里面的端口(必须对应容器端口)
- 创建方式
- kubectl expose deployment 名称 --port=8888 --target-port=80
- 或编写YAML
- apiVersion: v1
- kind: Service
- metadata:
- name: my-service
- spec:
- type: ClusterIP
- selector:
- app: nginx # 必须和 Pod 标签一致
- ports:
- - port: 8888 # Service 端口
- targetPort: 80 # Pod 端口
- 查看
- kubectl get svc
- kubectl get endpoints # 看背后绑定了哪些 Pod
- K8s 支持 把多个资源(Deployment + Service)写在同一个 YAML 文件里,用 --- 分隔就行
三个端口
- port:Service 自己的端口
- targetPort:Pod 里面的端口
- nodePort:外部访问的端口(NodePort 类型才有)
NodePort
- 作用:让集群外部的机器,可以通过「节点 IP + 固定端口」访问到集群内部的 Pod 服务
- 原理:浏览器 → 节点IP:NodePort → Service → Pod
- 开启方式:kubectl patch svc 服务名 -p '{"spec":{"type":"NodePort"}}'
- 或 YAML 里改:type: NodePort
- 查看:kubectl get svc 会出现:8888:32117/TCP,32117 就是外部访问端口 访问方式:curl http://192.168.xxx.xxx:32117
- NodePort 可以指定端口,在yml文件中
- ports:
- - port: 80
- targetPort: 80
- nodePort: 30002 # 固定端口,范围 30000-32767
cluster VS nodeport
- 对比维度 ClusterIP NodePort
- 访问范围 仅集群内部 Pod / 服务可访问 集群外部(浏览器、外部服务)可访问
- IP 特性 分配固定虚拟 ClusterIP,仅集群内路由 无额外 IP,复用节点物理 IP
- 端口特性 仅 Service 内部 port,无外部端口 开放 nodePort(30000-32767),外部直接访问
- 核心用途 微服务内部通信、服务发现 测试环境外部访问、简单对外服务
- 生产使用 业务服务默认类型 仅临时测试用,生产用 LoadBalancer/Ingress 替代
iptables vs ipvs
- iptables(默认)
- 通用、稳定
- 算法少:轮询、IP 绑定
- ipvs(性能更好,企业推荐)
- 内核态,更快
- 支持多种算法:rr、wrr、lc、ip_hash 等
- 生产环境一般都开 ipvs
- 开启 ipvs:kubectl edit configmap kube-proxy -n kube-system
- 把 mode: "" 改为:mode: "ipvs"
- 重启 kube-proxy:kubectl delete pod -n kube-system -l k8s-app=kube-proxy
sessionAffinity(IP 绑定)
- 作用:同一个 IP 永远访问同一个 Pod(类似 Nginx ip_hash)
- kubectl patch svc 服务名 -p '{"spec":{"sessionAffinity":"ClientIP"}}'
Service 怎么找到 Pod
- 通过标签(label)绑定
- Pod 有标签:app: nginx
- Service selector 写:app: nginx
- Service 自动找到所有带这个标签的 Pod
- 自动负载均衡
- Pod 挂了、重建,Service 自动更新
市面常用命令速查
- kubectl get svc # 看服务
- kubectl get ep # 看服务后端 Pod
- kubectl expose deploy xx --port=80 --target-port=80 # 创建服务
- kubectl patch svc xx -p '{"spec":{"type":"NodePort"}}' # 外部访问
- kubectl rollout status deploy xx # 看更新
总结
- Service 就是 Pod 的固定入口、负载均衡、自动发现
- 内部访问用 ClusterIP
- 外部访问用 NodePort
- 通过 label 找 Pod
- Pod IP 变了也不影响访问
污点和容忍度
核心
核心
- 污点打在节点上,不让普通 Pod 上来
- 容忍度写在 Pod 里,允许我上这个节点
基础概念
- 污点 Taint
- 作用在 Node 节点
- 告诉调度器:尽量别把 Pod 调度到我这
- 一个节点可以打多个污点
- Pod 必须容忍所有污点才能被调度上来
- 容忍度 Toleration
- 作用在 Pod
- 告诉调度器:我能容忍这个节点的污点
- 有容忍 ≠ 强制调度到该节点,只是允许上去
污点的 3 种类型
- 效果 含义
- NoSchedule 禁止新 Pod 调度上来,已在的 Pod 不驱逐
- NoExecute 无法容忍的 Pod 立即驱逐,非常强硬
- PreferNoSchedule 尽量不调度,不是强制
- 企业最常用:NoSchedule、NoExecute
命令
- 给节点打污点
- kubectl taint node 节点名 key=值:效果
- 示例:
- kubectl taint node k8s-node1 env=test:NoSchedule
- 删除污点(末尾加 -)
- kubectl taint node k8s-node1 env=test:NoSchedule-
- 查看节点污点
- kubectl describe node 节点名 | grep Taints
- 批量查看所有节点污点
- kubectl describe nodes $(kubectl get node | grep Ready | awk '{print $1}') | grep Taints
Pod 配置容忍度(YAML)
- 和containerd平级
- 精确匹配(Equal,生产推荐),key、value、effect 必须完全一致
- spec:
- tolerations:
- - key: "env"
- operator: "Equal"
- value: "test"
- effect: "NoSchedule"
- 存在匹配(Exists,简单),只要 key 存在就行,不用 value
- spec:
- tolerations:
- - key: "env"
- operator: "Exists"
- effect: "NoSchedule"
关键区别
- NoSchedule vs NoExecute
- NoSchedule:只拦新 Pod,不踢老 Pod
- NoExecute:踢走所有不容忍的现存 Pod
- Equal vs Exists
- Equal:key + value + effect 必须全匹配
- Exists:只看 key,不看 value
典型使用场景
- Master 节点不跑业务 Pod
- master 默认有污点,只允许系统组件
- GPU / 专用节点
- 只给特定 Pod 使用,不让普通业务占用
- 新节点暂不调度
- 测试稳定后再放开
- 节点维护
- 打 NoExecute,Pod 自动漂移走
k8s 三种探针
livenessProbe 存活探针
livenessProbe 存活探针
- 核心作用:检测容器进程是否卡死、无响应、程序崩溃
- 失败处理:连续探测失败,直接重启 Pod 容器
- 业务场景:服务假死、进程僵死、内存溢出卡死
- 生命周期:容器运行全程持续探测
readinessProbe 就绪探针
- 核心作用:检测容器是否完成初始化,可正常处理业务流量
- 失败处理:失败就把 Pod 从 Service 端点剔除,不再转发请求
- 业务场景:加载配置、连接数据库、缓存预热、启动初始化
- 生命周期:运行中持续探测,恢复正常重新加入流量池
startupProbe 启动探针
- 核心作用:专门监控启动缓慢的应用,判定容器是否启动完成
- 失败处理:超时未启动直接重启容器;启动成功后探针永久关闭
- 业务场景:Java 大应用、大数据组件、初始化耗时久程序
- 优先级:启动探针生效期间,存活、就绪探针暂停工作
四种探测方式
- httpGet:访问容器接口,2xx/3xx 状态码判定健康
- tcpSocket:检测端口能否正常连通
- exec 命令:容器内执行脚本命令,返回 0 为正常
- grpc:GRPC 服务健康检查
通用配置参数
- initialDelaySeconds:容器启动后多久开始首次探测
- periodSeconds:每次探测间隔时长
- timeoutSeconds:单次探测超时时间
- failureThreshold:连续失败多少次判定异常
- successThreshold:连续成功多少次判定恢复健康
三者核心区别
- 存活探针:管死活,死了就重启
- 就绪探针:管流量,没准备好就断流
- 启动探针:管启动,启动慢专用保护
Ingress
定义
定义
- 定义集群外部 → 内部的 HTTP/HTTPS 路由规则
- 类似 Nginx 的 server/location,做七层负载均衡
- 统一入口、域名管理、SSL 终止、路径转发、重写
Ingress vs Service
- 维度 Service Ingress
- 层次 四层(TCP/UDP) 七层(HTTP/HTTPS)
- 流量 内部东西流量 外部南北流量
- 作用 内部服务发现、负载均衡 外部暴露 Web 服务
- 访问 ClusterIP/NodePort/LB 域名 + 路径
- 能力 无路由 / 重写 / HTTPS 路由、重写、SSL、多域名
Nginx Ingress 三组件
- Ingress 资源:K8s 对象,写路由规则
- Ingress Controller:监听 APIServer,动态更新配置
- 反向代理(Nginx):真正接收请求、转发流量
关键配置
- ingressClassName: nginx:指定使用的 IngressClass
- host:域名(必须配 hosts 或 DNS)
- pathType: Prefix:前缀匹配;Exact:精确匹配
- nginx.ingress.kubernetes.io/rewrite-target: /:路径重写
单域名 Ingress YAML
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: ingress-single-domain
- namespace: default # 按需修改
- annotations:
- # Nginx Ingress 必须注解
- kubernetes.io/ingress.class: "nginx"
- # 自动重定向 http → https(可选)
- # nginx.ingress.kubernetes.io/ssl-redirect: "true"
- spec:
- rules:
- # 单个域名
- - host: www.example.com
- http:
- paths:
- # 根路径 / 转发到 web 服务
- - path: /
- pathType: Prefix
- backend:
- service:
- name: web-service # 你的 Service 名称
- port:
- number: 80 # Service 端口
多域名 Ingress YAML(HTTP)
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: ingress-multi-domain
- namespace: default
- annotations:
- kubernetes.io/ingress.class: "nginx"
- spec:
- rules:
- # 域名 1
- - host: www.example.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: web-service
- number: 80
- # 域名 2
- - host: api.example.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: api-service
- port:
- number: 8080
- # 域名 3
- - host: admin.example.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: admin-service
- port:
- number: 80
PV(PersistentVolume)持久化存储卷
定义
定义
- 由管理员创建的集群级存储资源
- 对底层存储(NFS、HostPath、Ceph、云盘)做统一抽象
- 生命周期独立于 Pod,Pod 删除数据不丢
PV 生命周期状态
- Available:可用,未被绑定
- Bound:已绑定到某个 PVC
- Released:PVC 已删除,PV 待回收
- Failed:回收失败
PV 回收策略
- Retain(保留):PVC 删除后,PV 仍保留数据,手动清理
- Delete(删除):PVC 删除,PV 与数据一起删除(云存储常用)
- Recycle(回收):旧版本,已废弃
PV 访问模式
- RWO – ReadWriteOnce:单节点可读写
- ROX – ReadOnlyMany:多节点只读
- RWX – ReadWriteMany:多节点可读写(NFS、Ceph)
PV 关键字段
- capacity.storage:容量(10Gi、50Gi)
- accessModes:访问模式
- persistentVolumeReclaimPolicy:回收策略
- storageClassName:存储类名称(用于自动绑定)
- hostPath / nfs:具体存储实现
PV 完整 YAML
- apiVersion: v1
- kind: PersistentVolume
- metadata:
- name: pv-nfs
- spec:
- capacity:
- storage: 10Gi
- accessModes:
- - ReadWriteMany
- persistentVolumeReclaimPolicy: Retain
- storageClassName: nfs-sc
- nfs:
- server: 192.168.1.100
- path: /data/nfs/pv1
PVC(PersistentVolumeClaim)存储申请
定义
定义
- 用户 / 业务使用,向集群 “申请” 存储
- 开发者只关心:要多大、什么访问模式、什么存储类
- 由系统自动匹配并绑定 PV
PVC 绑定逻辑
- PVC 声明容量、访问模式、storageClassName
- 系统寻找满足条件的空闲 PV
- 状态变为 Bound,即可被 Pod 挂载
PVC 关键字段
- resources.requests.storage:申请容量
- accessModes:必须与 PV 兼容
- storageClassName:必须与 PV 一致
- volumeName:可手动指定绑定某个 PV
PVC 完整 YAML
- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: pvc-nfs
- spec:
- accessModes:
- - ReadWriteMany
- resources:
- requests:
- storage: 5Gi
- storageClassName: nfs-sc
Pod 如何使用 PVC(挂载)
- volumes:
- - name: data-volume
- persistentVolumeClaim:
- claimName: pvc-nfs # 直接写 PVC 名称
- containers:
- - name: app
- volumeMounts:
- - name: data-volume
- mountPath: /data
ConfigMap(CM)配置管理
定义
定义
- 存储非敏感配置:配置文件、环境变量、命令行参数,也就是存储pod的配置信息
- 把配置从镜像里抽离,实现镜像与配置分离
- 不加密,不能存密码、密钥(敏感用 Secret)
ConfigMap 三种创建方式
- 从目录创建
- kubectl create configmap cm-app --from-file=./config
- 从文件创建
- kubectl create configmap cm-app --from-file=app.conf
- 从键值对创建
- kubectl create configmap cm-app --from-literal=env=prod --from-literal=port=8080
ConfigMap 两种使用方式
- 挂载为配置文件
- volumes:
- - name: config-volume
- configMap:
- name: cm-app
- containers:
- - name: app
- volumeMounts:
- - name: config-volume
- mountPath: /etc/app/conf.d
- readOnly: true
- 注入为环境变量
- containers:
- - name: app
- env:
- - name: APP_ENV
- valueFrom:
- configMapKeyRef:
- name: cm-app
- key: env
ConfigMap 完整 YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: cm-app
- data:
- # 键值对
- env: prod
- port: "8080"
- # 配置文件内容
- app.conf: |
- server {
- listen 8080;
- root /usr/share/nginx/html;
- }
注意事项
- ConfigMap 必须与 Pod 在同一命名空间
- 更新 ConfigMap 后:
- 挂载的文件会自动同步(延迟几分钟)
- 环境变量不会自动更新,需重建 Pod
- 不适合存敏感信息(密码、token、密钥)→ 用 Secret
Prometheus
基础概念
基础概念
- Prometheus:开源的监控 + 告警 + 时序数据库组合,Go 语言开发,专为云原生 / K8s 设计,常用于监控软件
- 时序数据:按时间顺序记录的指标数据,适合监控、运维、IoT、交易等场景
- 核心优势:多维度模型、灵活 PromQL、单机高性能、Pull 模型、服务发现、高效存储
核心组件
- Prometheus Server
- Retrieval:定期从目标拉取(pull) /metrics 指标
- TSDB:本地时序数据库,存时间序列数据
- PromQL Engine:执行查询语言
- Rule Evaluation:算记录规则、告警规则
- Exporter
- 把第三方服务(MySQL、Redis、主机、K8s)的指标转成 Prometheus 能识别的格式,暴露 /metrics
- 常用:node_exporter、mysqld_exporter、blackbox_exporter
- Push gateway(可选)
- 用于短生命周期任务推送指标
- 不建议长期使用,易数据污染
- Alertmanager
- 接收 Prometheus 告警
- 去重、分组、抑制、路由
- 发送到邮件、钉钉、微信、Webhook
- Grafana
- 可视化展示
- 对接 Prometheus 数据源
- 导入 Dashboard JSON 模板
完整工作流程
- Exporter / 应用暴露 /metrics 接口
- Prometheus 定时 Pull 抓取(默认 15s)
- 指标存入 TSDB 时序库
- PromQL 查询数据(UI / Grafana / API)
- 执行告警规则(满足条件持续 N 分钟触发)
- 告警发给 Alertmanager
- Alertmanager 处理并发送通知
- 可以使用grafana或者原生的UI实现数据可视化
核心配置(prometheus.yml)
- 静态抓取配置
- scrape_configs:
- - job_name: "node"
- static_configs:
- - targets: ["10.1.1.14:9100"]
- 告警规则示例(CPU 高负载)
- alert: HighCpuLoad
- expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
- for: 2m
- labels:
- severity: warning
- annotations:
- summary: "主机 CPU 使用率过高"
常用 Exporter 与端口
- node_exporter:Linux 主机监控 → 9100
- mysqld_exporter:MySQL 监控 → 9104
- prometheus server:自身监控 → 9090
- grafana:可视化 → 3000
关键特性
- 数据模型:指标名{标签1=值,标签2=值} 数值
- 抓取方式:默认 Pull,更稳定、易排错
- 服务发现:支持静态配置、K8s、文件 SD
- PromQL:强大查询语言,支持 rate、sum、avg、by 等
- 告警机制:先计算 → 满足持续时间 → 发 Alertmanager
- 存储高效:单数据点约 3.5byte,百万序列低成本
常见命令速查
- pkill prometheus && ./prometheus --config.file=prometheus.yml & # 重启 Prometheus
- kubectl create secret tls example-tls --cert=tls.crt --key=tls.key # 创建 TLS Secret(HTTPS 用)
- lsof -i:9090 # 查看端口
- lsof -i:9100 # 查看端口
- lsof -i:3000 # 查看端口
经典监控场景(CPU 告警)
- node_exporter 暴露 CPU 指标
- Prometheus 抓取 node_cpu_seconds_total
- 告警规则计算使用率 >90% 持续 2 分钟
- 发送到 Alertmanager → 钉钉 / 邮件通知
- Grafana 查看负载曲线定位问题
Grafana 的作用
- Grafana 是开源的时序数据可视化与监控告警平台
- 数据展示:把 Prometheus 等监控数据做成图表、仪表盘、曲线图
- 多数据源兼容:支持 Prometheus、MySQL、Elasticsearch、InfluxDB 等几十种数据源
- 可视化面板:拖拽式制作大盘,不用写代码,可导入现成 JSON 模板
- 监控告警:设置阈值、异常通知(邮件、钉钉、企业微信)
- Prometheus 负责采集存数据,Grafana 负责把数据变好看、好用、好报警
Prometheus 的 4 种指标类型(时序数据类型)
- Counter(计数器)
- 只增不减,用于统计总量
- 例:请求总数、CPU 总耗时、网卡流量总字节
- 示例:http_requests_total
- Gauge(仪表盘)
- 可增可减,实时当前值
- 例:CPU 使用率、内存占用、连接数、温度
- 示例:node_memory_Active_bytes
- Histogram(直方图)
- 统计数据分布,按区间计数
- 例:请求耗时分布、P99/P95 延迟
- Summary(摘要)
- 直接统计分位数(如 0.95、0.99)
- 例:接口响应时间分位数
扩展
- Pull vs Push:Prometheus 首选 Pull,更健康检查;短任务用 Pushgateway。
- 告警去重 / 抑制:避免风暴,比如主机宕机不再发服务告警。
- Grafana 模板:官方仓库直接导入 JSON,不用手动画面板。
- K8s 集成:自动发现 Pod/Service/Node,最主流监控方案。
- 数据保留:可通过 --storage.tsdb.retention.time 修改。
PromQL语法
4 种数据类型
4 种数据类型
- 瞬时向量 Instant Vector
- 一组时序,每个时序只有最新一个值,同一时间戳。例:node_cpu_seconds_total{mode="idle"}
- 范围向量 Range Vector
- 带 [时间窗口],取一段时间内的所有点,只能给函数用。例:node_cpu_seconds_total[5m]
- 标量 Scalar
- 单纯数字:1、100、0.5
- 字符串 String
- 几乎不用,忽略
标签匹配运算符(写过滤必用)
- = 完全相等
- != 不等
- =~ 正则匹配
- !~ 正则不匹配
- 示例:node_cpu_seconds_total{mode=~"idle|system|user"}
时间单位
- s 秒
- m 分钟
- h 小时
- d 天
- w 周
- y 年
- 示例:[1m]、[5m]、[1h]、[1d]
最核心两个函数:rate /irate(Counter 专用)
- rate()
- 求窗口内平均增长率
- 适合画图、趋势、告警
- rate(node_cpu_seconds_total[5m])
- irate()
- 取最后两个点计算瞬时速率
- 适合实时峰值、快速波动
- irate(node_network_receive_bytes_total[1m])
聚合函数
- sum() 求和
- avg() 平均
- max() 最大
- min() 最小
- count() 计数
- by /without(分组关键字)
- by(label):保留该标签分组(类似 group by)
- without(label):去掉该标签
- avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance)
向量运算(标签必须对齐)
- 支持:+ - * / % ^
- # 内存使用率 %
- 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100)
- # CPU 使用率
- 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
逻辑 / 集合运算
- and 交集
- or 并集
- unless 排除
offset 时间偏移
- 查过去某个时间的数据:
- node_load1 offset 1h
- rate(node_cpu_seconds_total[5m] offset 1d)
高频常用模板
- CPU 使用率:100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
- 内存使用率:100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100)
- 网络入口速率:irate(node_network_receive_bytes_total{device!="lo"}[1m])
- 请求 QPS:sum(rate(http_requests_total[5m])) by (path,status)
- 接口耗时(分位):histogram_quantile(0.95, sum(rate(demo_api_request_duration_seconds_bucket[5m])) by (le,path))
关键规则
- Counter 一定要用 rate/irate,不能直接用原始值
- 范围向量 [5m] 不能直接展示,必须套函数
- 运算时标签要完全匹配,否则无数据
- by /without 写在聚合函数里面或外面都可以
- 主机监控统一用 5m 窗口最稳
总结
- 查当前值 → 瞬时向量
- 查速率 → rate(指标[5m])
- 查分组 → by(instance)
- 查使用率 → 100 减空闲率
- 查历史 → offset
- 查波动 → irate
Alertmanager + Prometheus 告警规则
整体流程
整体流程
- Prometheus 按告警规则(alert.rules)计算 PromQL
- 满足条件且持续 for 时间 → 生成告警
- 发送给 Alertmanager
- Alertmanager 做去重、分组、抑制、路由
- 发送到:钉钉 / 邮件 / 企业微信 / Webhook
Alertmanager 核心知识点
- 核心 6 大能力
- 去重 Deduplication:相同告警只发一次
- 分组 Grouping:多条同类告警合并发送
- 抑制 Inhibition:重大告警屏蔽次要告警
- 路由 Routing:按标签分发不同接收人
- 模板 Templating:自定义消息格式
- 高可用 HA:多实例 Gossip 同步
- 配置结构(固定 5 部分)
- global: # 全局配置
- route: # 路由树(根路由+子路由)
- receivers: # 接收者(邮件、钉钉等)
- inhibit_rules: # 抑制规则
- templates: # 消息模板
- 路由 route
- 根路由参数
- group_by: ['alertname'] # 按哪些标签分组
- group_wait: 30s # 第一条告警等多久再发(批处理)
- group_interval: 5m # 同组下一批间隔
- repeat_interval: 3h # 未恢复告警重复发送间隔
- receiver: default-receiver # 默认接收者
- 子路由匹配
- match: 精确匹配
- match_re: 正则匹配
- 匹配成功不再向下匹配(树状路由)
- routes:
- - match:
- severity: critical
- receiver: dingtalk-critical
- 分组 vs 去重
- 分组:多条不同告警 → 合并成一条通知
- 去重:同一条告警重复触发 → 只发一次
- 抑制规则 Inhibition
- 作用:A 告警触发 → 抑制 B 告警,避免风暴
- inhibit_rules:
- - source_match:
- severity: critical
- target_match:
- severity: warning
- equal: [instance, alertname]
- 接收者 receivers
- 支持:
- email_configs
- webhook_configs(钉钉 / 企业微信)
- slack_configs
- pagerduty_configs
- 常用:send_resolved: true(发送恢复通知)
Prometheus 告警规则
- 固定结构
- groups:
- - name: node_alerts
- rules:
- - alert: HighCPUUsage
- expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 80
- for: 2m
- labels:
- severity: warning
- service: order
- env: prod
- annotations:
- summary: "CPU 使用率过高 {{ $labels.instance }}"
- description: "当前值:{{ $value }}%"
- alert:告警名(唯一)
- expr:PromQL 表达式(结果 > 0 触发)
- for:持续多久才触发(防抖)
- labels:用于 Alertmanager 路由 / 分组 / 抑制
- annotations:告警文案,支持变量
- 模板变量
- {{ $labels.instance }} 实例地址
- {{ $labels.job }} 任务名
- {{ $value }} 当前触发值
- {{ $labels.severity }} 级别
PromQL 告警模板
- CPU 使用率 > 80%:expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 80
- 内存使用率 > 85%:expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
- 磁盘使用率 > 90%:expr: 100 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100) > 90
- 服务宕机(up=0):expr: up{job="app"} == 0
- 接口 QPS 突降:expr: sum(rate(http_requests_total[5m])) by (instance) < 10
告警最佳实践
- 所有告警必须带 severity:critical/warning/info
- 必须带 env:dev/test/prod
- for 至少 1~2 分钟,避免抖动
- repeat_interval 生产用 1h~4h,别太频繁
- 关键服务用 critical,并开启抑制 warning
- 钉钉 / 企业微信用 webhook 接入
总结
- 规则写 PromQL,触发后发给 Alertmanager
- Alertmanager 负责:分组、去重、抑制、路由
- labels 做路由,annotations 做文案
- 抑制:重大告警屏蔽次要告警
- 分组:一次发一堆,不轰炸
Zabbix
Zabbix 整体架构
Zabbix 整体架构
- Zabbix Server:核心,接收数据、计算触发器、管理配置
- Database:存储配置与监控数据(MySQL / MariaDB)
- Web 界面:GUI 配置与查看监控
- Agent / Agent2:部署在被监控机,采集数据
- Proxy(可选):分布式代理,减轻 Server 压力
- 监控方式:Agent/Agent2、SNMP、JMX、IPMI
- 常用于监控硬件
Zabbix 5.0 重要特性(Agent2)
- Go 语言重写,性能更高
- 默认端口 10050
- 不能与旧 Agent 同时运行
- 配置文件:/etc/zabbix/zabbix_agent2.conf
- 协议:使用SMTP简单网络传输协议传输数据
服务端安装步骤(CentOS 7)
- 需要能够连接外网,比如网卡改为dhcp
- 关闭防火墙与 SELinux
- setenforce 0
- sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
- systemctl stop firewalld && systemctl disable firewalld
- 安装官方源(阿里云yum源)
- rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
- cat > CentOS-Base.repo <<EOF
- [base]
- name=CentOS-7 - Base - mirrors.aliyun.com
- baseurl=http://mirrors.aliyun.com/centos/7/os/x86_64/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- [updates]
- name=CentOS-7 - Updates - mirrors.aliyun.com
- baseurl=http://mirrors.aliyun.com/centos/7/updates/x86_64/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- [extras]
- name=CentOS-7 - Extras - mirrors.aliyun.com
- baseurl=http://mirrors.aliyun.com/centos/7/extras/x86_64/
- gpgcheck=1
- gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
- EOF
- 安装 Server、Agent、Web 环境
- yum install zabbix-server-mysql zabbix-agent -y
- yum install centos-release-scl -y
- yum install zabbix-web-mysql-scl zabbix-apache-conf-scl -y
- 安装数据库(MariaDB)
- yum install mariadb-server -y
- systemctl start mariadb && systemctl enable mariadb
- 初始化数据库
- mysql_secure_installation
- 创建 zabbix 库与用户
- create database zabbix character set utf8 collate utf8_bin;
- create user zabbix@localhost identified by 'fuyao666';
- grant all privileges on zabbix.* to zabbix@localhost;
- flush privileges;
- 导入初始数据
- zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix
- 配置 Server 数据库密码
- vi /etc/zabbix/zabbix_server.conf
- DBPassword=fuyao666
- 配置 PHP 时区
- vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf
- php_value[date.timezone] = Asia/Shanghai
- 启动服务
- systemctl restart zabbix-server zabbix-agent httpd rh-php72-php-fpm
- systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm
- Web 初始化
- 访问:http://IP/zabbix
- 默认账号:Admin
- 默认密码:zabbix
Agent2 安装(被监控端)
- 同步时间
- yum install ntpdate -y
- ntpdate cn.pool.ntp.org
- 安装源与 Agent2
- rpm -Uvh https://mirrors.aliyun.com/zabbix/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
- sed -i 's#http://repo.zabbix.com#https://mirrors.aliyun.com/zabbix#' /etc/yum.repos.d/zabbix.repo
- yum install zabbix-agent2 -y
- 配置 Agent2
- vi /etc/zabbix/zabbix_agent2.conf
- 修改:
- Server=Zabbix_Server_IP
- ServerActive=Zabbix_Server_IP
- Hostname=自定义主机名
- 启动并开机自启
- systemctl start zabbix-agent2 && systemctl enable zabbix-agent2
- 连通性测试(在 Server 上)
- yum install zabbix-get -y
- zabbix_get -s 客户端IP -p 10050 -k "agent.ping"
- 返回 1 表示通
Zabbix 核心基本概念
- Host(主机):被监控对象
- Host Group(主机组):主机逻辑分组,用于权限管理
- Item(监控项):具体采集指标(CPU、内存等)
- Trigger(触发器):阈值判断,生成 Problem/OK
- Event(事件):触发器状态变化
- Template(模板):监控项 + 触发器 + 图形的集合,可批量应用
- Application(应用集):监控项逻辑分组
- Action(动作):事件触发后的操作(发通知、执行命令)
- Escalation(升级):通知逐级发送
- Media(媒介):通知渠道(邮件、钉钉、短信)
端口说明
- zabbix server:10051
- zabbix agent/agent2:10050
常见问题
- Web 图形中文乱码
- yum -y install wqy-microhei-fonts
- cp /usr/share/fonts/wqy-microhei/wqy-microhei.ttc /usr/share/fonts/dejavu/DejaVuSans.ttc
- Agent 无法连接 Server
- 检查 Server 防火墙 10051 端口
- 检查 Agent 配置 Server、ServerActive、Hostname
- 用 zabbix_get 测试
- 数据库连接失败
- 检查 zabbix_server.conf 中的 DBPassword
- 检查 MariaDB 状态与权限
总结
- Server 管监控、Agent 采数据
- Agent2 用 Go,端口 10050
- 服务端配 DB、PHP 时区、Web UI
- 核心概念:主机 → 监控项 → 触发器 → 动作 → 通知
- 乱码装字体、不通查防火墙 / 配置
Zabbix 自定义监控
核心概念
核心概念
- Zabbix 监控方式
- 被动模式:Server 主动去 Agent 拿数据(常用)
- 主动模式:Agent 主动上报给 Server
自定义监控 = 自定义键值(Key)
- 配置文件:/etc/zabbix/zabbix_agentd.d/*.conf
- 格式:UserParameter=键值key,执行的命令
- 一个文件可以放无数个 UserParameter,不用分开多个文件。
配置固定套路
- 写 UserParameter 到 .conf 文件
- 重启 zabbix-agent:systemctl restart zabbix-agent
- 本地测试 key 是否可用:zabbix_get -s IP -k 键值 如果没有则使用yum安装
- Zabbix Web 创建监控项
- (可选)加图形、加触发器告警
消息中间件
是什么
是什么
- 消息中间件 = 系统之间的 “快递中转站”负责在应用之间异步传递消息,实现解耦、异步、削峰。
核心作用
- 解耦
- 系统 A 不直接调用系统 B,通过消息传递,互不影响
- 异步
- 不用等待对方处理完,主线程直接返回,提升速度
- 削峰 / 限流
- 高并发流量先进入队列,慢慢消费,防止压垮服务
核心概念
- 生产者 Producer:发消息的一方
- 消费者 Consumer:收消息、处理消息的一方
- 队列 Queue:存消息的地方
- 主题 Topic:发布 / 订阅模式用,一对多广播
- Broker:消息中间件服务端(服务器)
- ACK 确认:消费成功后告诉 MQ 删除消息
- 持久化:重启不丢消息
- 重试:消费失败重新投递
- 死信队列:处理失败多次的消息,进入死信排查
常见消息中间件
- RabbitMQ
- 开源、轻量、稳定
- 协议:AMQP
- 适合中小企业、常规业务
- 优点:可靠、延时消息、管理界面友好
- RocketMQ
- 阿里开源、高并发、高可用
- 适合电商、金融、高吞吐场景
- 优点:性能强、支持事务消息
- Kafka
- 超高吞吐、分布式、日志 / 大数据首选
- 适合日志收集、流计算、大数据同步
- 优点:速度极快、可持久、可回溯
两种消息模式
- 点对点(Queue)
- 一个消息只被一个消费者消费
- 类似:快递只能一个人签收
- 发布 / 订阅(Topic)
- 一个消息可以被多个消费者同时接收
- 类似:公众号推文,多人同时看
关键问题与解决方案
- 消息重复
- 原因:网络重试、ACK 失败
- 解决:业务幂等(唯一 ID、数据库去重)
- 消息丢失
- 解决:生产者确认、持久化、消费者 ACK
- 消息顺序
- 解决:单分区、单线程消费、按顺序投递
- 消息堆积
- 原因:消费太慢、消费者挂了
- 解决:增加消费者、优化消费逻辑、扩容分区
典型应用场景
- 订单创建 → 发送消息 → 扣库存、发短信、推送(解耦 + 异步)
- 秒杀、大促 → 队列削峰,防止系统崩溃
- 日志收集 → Kafka 统一收集
- 数据同步、异步通知、广播通知
阿里云 VPC 和ECS OSS RDS redis SLB
ECS教程:https://edu.aliyun.com/course/313238/?spm=a2cwt.28120015.3128400.16.1f40caf2WjI1wf
ECS教程:https://edu.aliyun.com/course/313238/?spm=a2cwt.28120015.3128400.16.1f40caf2WjI1wf
VPC 私有网络
VPC 私有网络
- 全称:Virtual Private Cloud
- 作用:你在阿里云上的独立私有网络,与其他用户隔离
- 核心组成
- 专有网络 VPC:大网段
- 交换机 vSwitch:子网,放在可用区
- 路由器:负责转发、上网
- 关键能力
- 隔离、安全
- 自定义网段、路由
- 绑定弹性公网 EIP
- 搭建内网环境(ECS、RDS、Redis 都在 VPC 里)
- 一句话:VPC = 阿里云上你的私有局域网
ECS 云服务器
- 相当于阿里云上的虚拟机
- 对应技术:KVM 虚拟化
- 核心作用:运行系统、部署应用、跑服务
- 关键概念
- 实例规格:CPU / 内存
- 系统盘 / 数据盘
- 镜像(操作系统)
- 安全组(防火墙)
- 弹性公网 IP(EIP):只有具有EIP才能够和外网连接
- 一句话:ECS = 阿里云上的云电脑 / 云服务器
OSS 对象存储
- 全称:Object Storage Service
- 用途:存文件、图片、视频、安装包、备份
- 特点
- 无限容量
- 按使用付费
- 提供 HTTP/HTTPS 访问
- 可做静态网站、图床、日志存储
- 关键:不支持格式化、不能当硬盘挂载
- 一句话:OSS = 阿里云上的无限网盘 / 文件仓库
RDS 云数据库
- 全称:Relational Database Service
- 托管的关系型数据库
- 支持:MySQL、SQL Server、PostgreSQL 等
- 优势
- 自动备份、高可用
- 主从、读写分离
- 监控、扩容、免运维
- 一句话:RDS = 阿里云托管的 MySQL 等数据库,不用自己装、自己维护
Redis 云数据库(云缓存)
- 基于 Redis 的内存型缓存 / 数据库
- 作用
- 热点数据缓存
- 分布式锁
- 计数器、限流
- 消息队列
- 特点:极快、内存存储、支持持久化、集群
- 一句话:Redis = 高速内存缓存,扛高并发、加速业务
SLB 负载均衡(ALB、CLB(常用))
- 全称:Server Load Balancer(现在叫 CLB)
- 作用:把用户请求均匀分给多台 ECS
- 核心能力
- 流量分发
- 健康检查
- 高可用
- 公网 / 内网负载均衡
- 一句话:SLB = 流量调度器,保证不宕机、扛高并发
openstack私有云
整体认知
整体认知
- OpenStack 不是单个软件,是一套开源 IaaS(基础设施即服务) 云平台组件集合
- 作用:搭建私有云 / 公有云,提供虚拟机、网络、存储等云服务
- 类似:K8s = 多组件协同,OpenStack 也是一堆组件一起工作
- OpenStack 是开源 IaaS 云平台,由 Keystone、Nova、Neutron、Glance、Cinder 等组件组成,
- 用于快速搭建私有云 / 公有云,统一管理虚拟机、网络和存储
6 大核心组件
- Keystone
- 身份认证、登录、权限、Token→ 类比:门禁系统 / IAM
- Nova
- 虚拟机生命周期管理(创建、删除、调度)→ 核心计算服务,调用 KVM 跑虚拟机
- Neutron
- 虚拟网络:网络、子网、路由、浮动 IP、安全组→ 类比:VPC、路由器、公网 IP
- Glance
- 系统镜像管理(CentOS、Ubuntu、Windows)→ 类比:镜像市场
- Cinder
- 块存储(云硬盘),可挂载、卸载、持久化→ 类比:云盘 ESSD
- Horizon
- Web 管理界面(控制台)→ 所有操作的可视化入口
其他重要组件
- Swift:对象存储(存图片、视频、备份,类似 OSS/S3)
- Heat:编排服务(模板一键部署资源,类似 Terraform)
- Ceilometer:监控、计量、计费
组件协作流程
- 用户先经过 Keystone 认证
- 通过 Horizon 界面 发起创建虚拟机请求
- Nova 负责创建虚拟机
- Glance 提供镜像
- Neutron 分配网络、IP
- Cinder 挂载云盘
- Ceilometer 全程监控
部署架构
- 控制节点:核心大脑:Keystone、Glance、Nova 管理、Neutron 管理、数据库、消息队列
- 网络节点:负责内外网通信、路由、NAT、浮动 IP
- 计算节点:真正跑虚拟机,用 KVM 虚拟化
- 存储节点:提供 Cinder 块存储、Swift 对象存储
PVE(Proxmox VE)
基本概念
基本概念
- PVE 是开源免费的企业级虚拟化平台,基于 Debian Linux
- 作用:一台物理机虚拟出多台独立虚拟机 / 容器
- 核心技术:KVM(虚拟机) + LXC(系统容器)
- 提供 Web 管理界面、集群、HA、备份、存储、网络一体化管理
PVE 包含的两大虚拟化
- KVM 虚拟机
- 完整硬件虚拟化
- 可装 Windows、Linux、BSD 等任何系统
- 隔离性强、稳定、生产环境主力
- LXC 容器
- 轻量级系统容器
- 共享内核、启动快、省资源
- 适合跑服务、应用、小业务
PVE 核心功能
- Web 管理界面:浏览器直接操作,无需客户端
- 集群管理:多台 PVE 组成集群,统一管理
- HA 高可用:节点故障,虚拟机自动迁移
- 在线迁移:虚拟机不停机迁移到其他节点
- 备份与恢复:支持定时备份、快照
- 多种存储支持:LVM、ZFS、Ceph、NFS、iSCSI
- 软件定义网络 SDN:虚拟交换机、网桥、VLAN、防火墙
- API 支持:可自动化、对接第三方平台
PVE 存储知识
- 支持的存储类型
- 本地存储:Directory、LVM、LVM-Thin、ZFS
- 网络存储:NFS、iSCSI、Ceph、GlusterFS
PVE 网络基础
- 网桥(Bridge):虚拟机通过网桥联网
- VMbr0:PVE 默认管理网桥
- 支持 VLAN、防火墙、 bonding、多网卡聚合
- 虚拟机网卡桥接到网桥上,和物理机同网段 / 不同网段均可
PVE 常用操作
- 创建 / 删除 / 启动 / 停止虚拟机
- 克隆虚拟机、模板制作
- 快照与回滚
- 备份(.vma 格式)
- 在线迁移
- 增加硬盘、扩容磁盘
- 配置网络、VLAN
- 集群添加 / 删除节点
PVE 与其他虚拟化对比
- PVE:开源免费、KVM+LXC、Web 管理、轻量、超融合
- VMware ESXi:商业、功能强、生态成熟、收费
- Hyper-V:微软、Windows 服务器自带
- KVM:底层技术,不是平台
- PVE 是基于 Debian 的开源虚拟化平台
- 底层使用 KVM 虚拟化和 LXC 容器
- 提供 Web 界面、集群、HA、备份、存储、网络统一管理
- 适合企业虚拟化、私有云、All in One 等场景
- 常见的虚拟化技术分别有:KVM VMware
日志分析ELK
ELK 整体介绍
ELK 整体介绍
- ELK = Elasticsearch + Logstash + Kibana
- Elasticsearch(ES):分布式存储、搜索、分析引擎、Nosql数据库(属于非关系型)
- Logstash:日志采集、清洗、过滤、转发(重量级)
- Kibana:Web 可视化界面、图表、监控
- Filebeat:轻量级日志采集器,替代 Logstash 客户端
- 常用架构
- ELK:App → Logstash → ES → Kibana
- EFK:App → Filebeat → ES → Kibana
- 企业标准:Filebeat → Logstash → ES → Kibana
ES 核心概念
- 关系型数据库 Elasticsearch
- 数据库(database) 索引(index)
- 表(table) 类型(type)
- 行(row) 文档(document)
- 列(column) 字段(field)
- Cluster:集群,一个或多个节点
- Node:单个 ES 实例
- Shard:分片,提升并发与存储
- Replica:副本,保证高可用
- 倒排索引:ES 快速搜索的核心结构
- 集群健康状态
- green:主副分片都正常
- yellow:主分片正常,副本异常
- red:主分片异常,数据风险
- 端口
- 9200:HTTP/API 访问
- 9300:集群通信
ES 基本操作(RESTful API)
- GET _cluster/health?pretty # 集群健康
- GET _cat/indices?v # 查看所有索引
- GET _cat/nodes?v # 查看节点
- PUT /my-index # 创建索引
- POST /my-index/_doc/1 # 插入文档
- { "title":"ES入门","author":"test","year":2025 }
- GET /my-index/_search # 查询所有文档
- { "query": { "match_all": {} } }
- GET /my-index/_search # 条件查询
- { "query": { "match": { "title": "ES" } } }
- POST /my-index/_update/1 # 局部更新(推荐)
- { "doc": { "year": 2026 } }
- DELETE /my-index # 删除索引
ES 部署要点
- 安装 JDK 1.8(不要用系统自带 OpenJDK)
- 配置 elasticsearch.yml
- cluster.name
- node.name
- network.host: 0.0.0.0
- discovery.zen.ping.unicast.hosts
- 启动:systemctl start elasticsearch
- 集群防脑裂
- discovery.zen.minimum_master_nodes: (N/2)+1
Logstash 知识点
- 作用:采集 → 过滤 → 输出到 ES
- 三大组件
- Input:输入源(file、beats、stdin)
- Filter:过滤、解析(可选)
- Output:输出(elasticsearch、stdout)
- 标准配置结构
- input { ... }
- filter { ... }
- output { ... }
- 典型配置
- input {
- beats { port => 5044 }
- }
- output {
- elasticsearch {
- hosts => "http://elasticsearch:9200"
- index => "nginx-access-%{+YYYY.MM.dd}"
- }
- stdout { codec => rubydebug }
- }
- 启动命令
- ./logstash --path.settings /etc/logstash -f 配置文件.conf
- 端口:5044:接收 Filebeat 数据
Kibana 知识点
- 作用:ES 的 Web 界面,查看日志、做图表、监控集群 端口:5601
- 配置关键
- server.host: 0.0.0.0
- elasticsearch.url: http://ES_IP:9200
- 核心操作
- Management → Index Patterns(创建索引匹配)
- Discover(查看日志)
- Visualize(做图表)
- Dashboard(仪表盘)
- 汉化
- Kibana_Hanization 工具
- python main.py /usr/share/kibana
Filebeat 知识点
- 核心作用
- 采集日志:读取服务器上的系统日志、Nginx/Apache 日志、应用日志等
- 轻量低耗:占用内存、CPU 极少,适合部署在所有业务机器
- 可靠传输:自带断点续传,日志不丢失、不重复
- 转发数据:可直接发给 ES,或发给 Logstash 做清洗过滤
- 简单过滤:支持按关键字包含 / 排除,只收集需要的日志
- 为什么用 Filebeat
- 超轻量、资源占用极低
- 适合部署在业务服务器
- Logstash 太重,不适合客户端
- 可横向扩展,每台机器独立部署
- 支持多种输入(log 文件、系统日志、容器日志等)
- 两种输出
- 直接输出到 ES(EFK)
- 输出到 Logstash(推荐)
- 核心配置(输出到 Logstash)
- filebeat.inputs:
- - type: log
- enabled: true
- paths:
- - /var/log/*.log
- - /var/log/httpd/access_log
- output.logstash:
- hosts: ["Logstash_IP:5044"]
- Logstash 接收 Filebeat
- input {
- beats {
- port => 5044
- }
- }
- output {
- elasticsearch {
- hosts => ["ES_IP:9200"]
- index => "filebeat-%{+YYYY.MM.dd}"
- }
- }
- 日志过滤
- include_lines: ['Installed'] 只收集含关键字行
- exclude_lines 排除行
标准实验环境(四节点)
- kibana:10.1.1.11:5601
- elasticsearch:10.1.1.12:9200
- logstash:10.1.1.13:5044
- filebeat:10.1.1.14
补充知识点
- Filebeat 优于 Logstash 的地方
- 轻量、低资源
- 部署简单
- 断点续传,不丢日志
- ES 分片与副本作用
- 分片:提高并发、分散存储
- 副本:高可用、负载均衡
- 日志采集最佳实践
- 业务机:Filebeat
- 清洗过滤:Logstash
- 存储:ES
- 展示:Kibana
- 常见日志路径
- /var/log/messages
- /var/log/yum.log
- /var/log/httpd/access_log
- /var/log/nginx/access.log
- 为什么用 Filebeat 不用 Logstash 直接采集?
- Logstash 重,耗 CPU / 内存
- Filebeat 极轻量,适合部署在所有机器
- 为什么按天建索引?
- 便于冷热数据管理
- 查询更快
- 可按日期删除旧日志
- fields_under_root 作用
- 把自定义字段放到日志顶层,ES 查询更方便。
速记
- ES:存数据、搜数据
- Logstash:收数据、洗数据
- Kibana:看数据、画图表
- Filebeat:轻量采集、不占资源
导入nginx日志
- 环境与目录
- elk/
- ├── docker-compose.yml
- ├── filebeat/
- │ └── filebeat.yml
- ├── logstash/
- │ └── logstash.conf
- └── nginx/
- └── logs/ # 用来存放 Nginx 的 access.log 和 error.log
- 编写docker-compose.yml文件
- version: '3'
- services:
- elasticsearch:
- image: elasticsearch:7.17.21
- container_name: es
- environment:
- - discovery.type=single-node
- - ES_JAVA_OPTS=-Xms512m -Xmx512m
- ports:
- - "9200:9200"
- networks:
- - elk
- kibana:
- image: kibana:7.17.21
- container_name: kibana
- environment:
- - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ports:
- - "5601:5601"
- depends_on:
- - elasticsearch
- networks:
- - elk
- logstash:
- image: logstash:7.17.21
- container_name: logstash
- volumes:
- - ./logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ports:
- - "5044:5044"
- depends_on:
- - elasticsearch
- networks:
- - elk
- filebeat:
- image: elastic/filebeat:7.17.21
- container_name: filebeat
- user: root
- volumes:
- - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
- - ./nginx/logs:/var/log/nginx
- depends_on:
- - logstash
- networks:
- - elk
- nginx:
- image: nginx:1.24
- container_name: nginx-demo
- ports:
- - "8080:80"
- volumes:
- - ./nginx/logs:/var/log/nginx
- networks:
- - elk
- networks:
- elk:
- driver: bridge
- 配置 Filebeat:采集 Nginx 日志
- 修改 filebeat/filebeat.yml,确保它能读取到 Nginx 日志,并加上自定义字段,方便 Logstash 区分
- filebeat.inputs:
- - type: log
- enabled: true
- paths:
- - /var/log/nginx/access.log # 对应容器内的日志路径
- fields:
- log_type: nginx_access # 标记为 Nginx 访问日志
- fields_under_root: true # 把字段放到日志顶层
- output.logstash:
- hosts: ["logstash:5044"] # 输出到 Logstash
- 配置 Logstash:接收并写入 ES
- 修改 logstash/logstash.conf,配置输入和输出,把 Nginx 日志写入 Elasticsearch:
- input {
- beats {
- port => 5044 # 接收 Filebeat 的数据
- }
- }
- output {
- # 只把 nginx_access 类型的日志写入 Nginx 索引
- if [log_type] == "nginx_access" {
- elasticsearch {
- hosts => ["http://elasticsearch:9200"]
- index => "nginx-access-%{+YYYY.MM.dd}" # 按天生成索引
- }
- }
- stdout {
- codec => rubydebug # 控制台打印日志,方便排错
- }
- }
自动批量化处理 ansible
Ansible 是什么
Ansible 是什么
- 自动化运维工具:批量配置、应用部署、任务执行
- 无代理(agentless):不需要在被控机装客户端,只靠 SSH + Python
- 配置文件:YAML 格式(Playbook)
- 优点:简单、轻量、易读、幂等
- 使用shell的缺点
- 管理的机器平台不一致,脚本可能不具备通用性。
- 传密码麻烦(在非免密登录的环境下, 需要expect来传密码)
- 效率较低,循环1000次也需要一个一个的完成,如果用&符放到后台执行,则会产生1000个进程
核心架构
- 控制节点:安装 Ansible,下发任务
- 被管理节点:不需要装 Ansible,只开 SSH
- Inventory:主机清单(hosts 文件)
- Module:模块(执行具体操作)
- Playbook:自动化剧本(任务编排)
- Ad-Hoc:临时命令(一次性执行)
Ansible 执行模式
- Ad-Hoc 模式(临时命令模式)
- 执行单条命令 / 单个模块
- 临时用、不用写文件
- 相当于 Linux 里的单行命令
- 快速测试、快速批量执行
- Playbook 模式(剧本 / 自动化模式)
- 用 YAML 写任务列表
- 可重复执行、幂等、有序执行
- 适合复杂流程:安装→配置→启动→巡检
- 企业最常用、最核心模式
核心概念
- Inventory(主机清单)
- 存放要管理的机器 IP / 分组
- 默认路径:/etc/ansible/hosts 告诉 ansible 要管理哪些机器
- 支持分组、连续 IP、通配符
- 例子
- [web]
- 192.168.160.10
- 192.168.160.11
- [db]
- 192.168.160.20
- Module(模块)
- Ansible 自带大量模块,相当于 “命令插件”
- 常用:
- ping:测试连通性
- command:执行命令(不经过 shell)
- shell:执行命令(支持管道、重定向)
- copy:推送文件
- file:创建目录 / 改权限
- yum:安装软件
- service/systemd:管理服务
- script:执行本地脚本
- template:模板渲染
- get_url:下载文件
- Ad-Hoc 命令
- 一次性、临时执行命令
- ansible 主机组 -i 清单文件 -m 模块 -a "参数"
- 例子
- ansible all -i hosts.ini -m ping
- ansible web -i hosts.ini -m shell -a "ls /tmp"
- Playbook(剧本)
- YAML 格式
- 可重复执行、幂等
- 结构:hosts → become → tasks
- 示例:
- - hosts: web
- become: yes
- tasks:
- - name: 安装 nginx
- yum:
- name: nginx
- state: present
- - name: 启动 nginx
- service:
- name: nginx
- state: started
- enabled: yes
- 执行:
- ansible-playbook -i hosts.ini nginx.yml
Role(角色)
- 高级封装
- 把任务、变量、模板、文件模块化
- 便于复用、大型项目必备
Ansible 执行流程
- 读取 ansible.cfg
- 加载 Inventory 主机列表
- 加载对应模块
- 生成本地临时 Python 脚本
- 通过 SSH 传到被控机 ~/.ansible/tmp/ 配置免密登录(必须做!)通常使用生成密钥 然后分发下去
- 加执行权限
- 执行并返回结果
- 删除临时文件
安装与配置
- 安装(yum)
- yum install epel-release -y
- yum install ansible -y
- 配置免密 SSH
- ssh-keygen -t rsa
- ssh-copy-id root@192.168.160.8
- ssh-copy-id root@192.168.160.9
- 测试连通性
- ansible all -i hosts.ini -m ping
- 返回 pong 即成功
最常用模块
- 系统类
- ping:连通性测试
- command:执行命令(无管道)
- shell:执行命令(支持管道)
- script:运行本地脚本到远端
- 文件类
- copy:主控端 → 远端 传输文件
- src:源文件 dest:目标路径 force=yes/no:是否覆盖
- backup=yes:覆盖前备份 owner/group/mode:权限
- fetch:远端 → 主控端 拉取文件
- src:源文件 dest:目标路径
- file:创建目录、改权限、删文件
- 常用参数:path:路径
- state:状态(directory → 创建目录 touch → 创建文件 absent → 删除 link → 软链接 hard → 硬链接)
- owner、group、mode:权限
- owner: bin group: daemon mode: '0777'
- template:渲染 Jinja2 模板
- 软件包
- yum:安装 / 卸载 state(状态)
- state=present:安装
- state=absent:卸载
- 服务
- service/systemd
- state=started:启动
- state=stopped → 停止
- state=restarted → 重启
- enabled=yes:开机自启
- 用户
- user:创建用户
- name:用户名 uid:指定 UID system=yes:系统用户 shell:登录 shell
- password:密码(必须加密) generate_ssh_key=yes:生成密钥 remove=yes:删用户并删家目录
- group:创建组
- authorized_key:分发公钥
handler + notify
- handler = 备用任务;notify = 触发信号
- 场景:修改了 Nginx 配置文件 → 必须重启 Nginx 才能生效 用途:改配置 → 重启服务;不改 → 不重启
- 如果配置没变化,就不重启
- 如果配置被修改,就自动重启
- 实例:
- - hosts: web
- tasks:
- - name: 推送 nginx 配置
- copy:
- src: nginx.conf
- dest: /etc/nginx/nginx.conf
- notify: 重启 nginx # 这里发信号
- handlers:
- - name: 重启 nginx # 名字必须和 notify 完全一样!
- service:
- name: nginx
- state: restarted
- 规则
- handlers 里的任务默认不执行
- 只有 tasks 里的任务状态是 changed(修改了)
- 并且写了 notify: 名字
- 才会在 所有 tasks 执行完后,执行一次 handler
Playbook 关键特性
- 幂等性:多次执行效果一样,不会重复安装
- YAML 格式:缩进严格
- become: yes:sudo 提权
- tasks 按顺序执行
Ansible 返回颜色含义
- 绿色:没变化
- 黄色:执行了改动
- 红色:失败
- 紫色:警告
企业常用场景
- 服务器初始化
- 批量部署 Nginx/Tomcat
- 批量改密码
- 批量分发密钥 / 配置
- K8s 节点初始化
- 配置巡检
- 应用自动化发布
速记
- Ansible:无代理、SSH 批量自动化
- Inventory:主机清单
- Module:执行动作
- Ad-Hoc:临时命令
- Playbook:自动化剧本
- 核心优势:简单、轻量、幂等、不用装客户端
分布式存储之Ceph
Ceph 概述
Ceph 概述
- 定义:Ceph 是统一分布式存储系统,把多台机器硬盘整合成一个超大、无限扩容、高可靠的存储池
- 同时支持
- 文件存储(CephFS):像普通目录一样挂载使用
- 块存储(RBD):像硬盘一样格式化、挂载
- 对象存储(RADOSGW):S3/Swift 接口,存海量文件 / 图片 / 视频
- 核心特点
- 高可靠:多副本、自愈、自管理
- 高可扩展:理论无限扩容
- 高性能:分布式并行读写
- 高自动化:自动复制、恢复、重平衡
- 底层引擎:RADOS
- 全称:Reliable Autonomous Distributed Object Store
- Ceph 所有数据最终都存在 RADOS
- 对外不直接用 RADOS,而是通过 4 种接口:
- LIBRADOS:开发库(C/C++/Python/Java)
- CEPH FS:文件存储
- RBD:块存储
- RADOSGW:对象存储网关
Ceph 数据存储流程
- 核心层级顺序
- 文件 → 对象 Object → 归置组 PG → CRUSH 算法 → OSD 节点
- 分步流程
- 文件切片
- 无论块、对象、文件存储,统一把文件切分成固定大小Object 对象(默认 2M/4M)。
- 生成唯一 OID
- 由文件唯一 ID (ino)+ 分片编号 (ono) 组成 OID,绑定文件与分片从属关系。
- 对象映射 PG
- OID 经过哈希运算,对 PG 总数取模,映射到对应PG 归置组。
- PG 是逻辑索引,统一管理一组对象
- 数据迁移、副本同步以 PG 为最小单位
- PG 副本策略
- 按照设定副本数,生成多个 PG 副本。
- CRUSH 寻址落盘
- 通过CRUSH 算法,将 PG 精准分发到不同物理 OSD 节点,实现高可用、均衡分布。
- 同一 PG 副本不会落在同一节点
- 首个 OSD 为主副本,其余为从副本
- 核心组件作用
- Object:Ceph 最小存储数据单元
- PG 归置组:对象聚合层,简化寻址、统一调度、均衡数据
- CRUSH:去中心化分布式寻址算法,负责数据精准放置
- OSD:实际磁盘存储节点,负责数据读写、副本同步、故障恢复
- 关键优点
- 统一对象模型,读写效率高
- PG 聚合减少寻址压力
- CRUSH 自动均衡数据、故障自动迁移
- 多副本保障数据安全
Ceph 架构总览(自上而下)
- 客户端 / APP / 虚拟机
- 访问接口层
- RADOSGW:对象存储(S3/Swift)
- RBD:块存储
- CephFS:文件存储
- LIBRADOS:统一访问底层 RADOS
- RADOS:底层对象存储引擎(OSD+Monitor+MGR)
核心组件
- OSD(Object Storage Device)—— 最重要
- 真正存数据的地方,一块盘 = 一个 OSD
- 负责:存储、副本、恢复、重平衡、心跳
- 集群最少 2 个 OSD
- MON(Monitor)—— 大脑
- 维护集群状态、映射表、认证、仲裁(quorum)
- 必须 奇数个(1/3/5),防止脑裂
- 集群最少 1 个 MON
- MGR(Manager)—— 管家
- Luminous 新增,分担 MON 压力
- 提供:监控、告警、Web UI、管理接口
- MDS(Metadata Server)—— 文件存储专用
- 只给 CephFS 用
- 管理目录、文件名、权限等元数据
- RGW(RADOS Gateway)—— 对象网关
- 提供 S3/Swift RESTful API
- 让 Ceph 变成对象存储服务
核心概念补充
- Pool(存储池)
- 逻辑存储分区,类似 “大目录”
- 数据先写 Pool,再由 CRUSH 算法分布到 OSD
- Pool 属性:PG 数量、副本数、存储类型
- PG(Placement Group,放置组)
- 数据分片的最小管理单元
- 1 个 Pool 包含多个 PG
- 1 个 PG 映射到一组 OSD(如 3 副本→3 个 OSD)
- PG 数一般设为 2 的幂,5 个 OSD 以内常用 128/64
- CRUSH 算法
- Ceph 核心数据分布算法
- 功能:把 Object → PG → OSD 映射
- 特点:
- 伪随机:同一 PG 每次映射 OSD 固定
- 可扩展:新增节点自动重平衡
- 高可用:副本分布在不同故障域(机架 / 机房)
- 副本机制
- 默认 3 副本:1 主 2 从
- 写入:主 OSD 写成功后同步到从 OSD
- 读取:就近读取任意副本
Ceph 集群部署(关键步骤)
- 环境准备(所有节点)
- 4 台主机:node1/2/3(集群)+ client(客户端)
- 静态 IP、主机名解析、关闭防火墙 / SELinux、时间同步
- 集群节点额外磁盘(/dev/sdb,不分区)
- 部署流程(node1 为部署节点)
- SSH 免密:node1 免密登录所有节点
- 安装 ceph-deploy:仅 node1,需要先执行yum install -y python-setuptools
- 创建集群:ceph-deploy new node1
- 安装 Ceph:集群节点装 ceph + ceph-radosgw
- 客户端:装 ceph-common
- 创建 MON:至少 3 个(node1/2/3)
- 创建 MGR:主备模式
- 创建 OSD:ceph-deploy osd create --data /dev/sdb 节点
- 常见问题
- 时间不同步:clock skew → 用 crontab 定时 ntpdate
- MON 奇数个:防止脑裂(quorum 仲裁)
三大存储使用
- CephFS 文件存储
- 像 NFS,直接挂载目录
- 支持 POSIX 权限、目录树、多客户端同读同写
- 用途:NAS、共享目录、集群文件系统
- 依赖:MDS 元数据服务
- RBD 块存储
- 像 虚拟硬盘 /dev/rbd0
- 支持格式化、挂载、在线扩容
- 不能多客户端同时写(单写多读)
- 用途:虚拟机盘、数据库盘、云主机
- RADOSGW 对象存储
- 类似 阿里云 OSS、AWS S3
- 结构:Bucket(桶)+ Object(对象),无目录树
- RESTful API,兼容 S3 / Swift
- 用途:图片、视频、归档、静态资源、海量非结构化数据
- 一句话区分:
- 文件:有目录、有权限、多人读写
- 块:像硬盘、高性能、单写
- 对象:扁平结构、无限扩容、互联网海量数据
对象存储 vs 文件 / 块存储(核心区别)
- 维度 文件存储(CephFS) 块存储(RBD) 对象存储(RGW)
- 访问方式 目录 / 文件(/a/b/c) 硬盘(/dev/sdb) Bucket+Object(s3://)
- 适用场景 共享目录、多客户端读写 虚拟机、数据库、单客户端 海量文件、归档、互联网
- 结构 树形目录 块 / 扇区 扁平结构,无目录
- 扩展性 好 好 最好(无限)
- 性能 中等 高 中高
底层架构:RADOS(数据引擎)
- 架构分层
- APP/VM
- ↑
- RGW RBD CephFS ← 上层接口
- ↑
- LIBRADOS ← 开发库
- ↑
- RADOS ← 底层引擎(OSD+MON+MGR)
- RADOS = Ceph 的心脏:所有数据最终存在这里,提供高可靠、自修复、自平衡
- 数据写入流程(核心原理)
- 文件 → 对象 → PG → OSD
- 文件切分成 Object(2M/4M)
- Object 哈希 → PGID(放置组)
- PG 通过 CRUSH 算法 → 映射到多个 OSD(默认 3 副本)
- 关键概念
- Pool(存储池):逻辑隔离区,管理 PG、副本数、策略
- PG(放置组):数据最小管理单元,多个 Object 组成 1 个 PG
- CRUSH 算法:Ceph 灵魂,无中心、伪随机、固定映射、故障域隔离
- 一句话总结:Pool → PG → OSD
三大存储使用实操
- CephFS 文件存储
- 创建 2 个 Pool:数据池 + 元数据池
- 创建 MDS
- 创建文件系统:ceph fs new cephfs 元数据池 数据池
- 客户端挂载:
- mount -t ceph mon节点:6789:/ /mnt -o name=admin,secretfile=密钥文件
- RBD 块存储
- 创建 Pool:ceph osd pool create rbd_pool 128
- 初始化:rbd pool init rbd_pool
- 创建镜像:rbd create volume1 --pool rbd_pool --size 5G
- 映射:rbd map rbd_pool/volume1 → /dev/rbd0
- 格式化、挂载、在线扩容
- RGW 对象存储
- 创建 RGW:ceph-deploy rgw create node1(端口 7480)
- 创建用户:radosgw-admin user create --uid=testuser
- 用 s3cmd 操作:mb(建桶)、put(上传)、get(下载)
对象存储特点
- 扁平结构:无目录,只有 Bucket+Object
- 无限扩容:理论无上限
- RESTful API:HTTP 直接访问
- 高可用:多副本、自修复
- 适合非结构化数据:图片、视频、归档
Ceph + OwnCloud 自建网盘
- 架构:用户 → OwnCloud(Web)→ Ceph RGW(S3)
- 用途:私有云盘、企业文件共享、替代网盘
Jenkins
AI 大模型、生成式技术、Agent 与 RAG
AI 大模型、生成式技术、Agent 与 RAG
核心概念区分:大语言模型(LLM)& 通用预训练生成模型
核心概念区分:大语言模型(LLM)& 通用预训练生成模型
- 大语言模型(LLM)
- 仅以文本为核心输入输出,专注文字理解、对话、文案、代码、长文本总结、逻辑推理。
- 代表产品:豆包、通义千问、元宝 LLM、GPT、Claude、DeepSeek、Kimi、Qwen 系列
- 核心用途:人机对话、文档处理、问答、代码生成、逻辑分析。
- 通用预训练生成模型(通才多模态模型)
- 以 Seed 为基础基座的全品类生成模型,不局限文本,可同时处理图像、音频、视频、文字,分为单模态生成模型与多模态通用模型
- 单模态和多模态的区别
- 单模态:定义:仅支持一种数据类型输入输出,只专精一类内容生成,不能跨媒介处理
- 多模态:定义:同时兼容文本、图片、音频、视频多种媒介,可以跨类型交互。
- 单模态细分赛道:
- 生成类型 技术路线 / 代表模型 核心能力
- 文本生成 LLM(GPT、Claude、DeepSeek、国产 DeepSeek/Kimi/Qwen) 文字对话、写作、代码、长文本解析
- 图像生成 Diffusion 扩散模型(Stable Diffusion、Midjourney、Image2.0) 绘图、修图、图像理解、图文转换
- 音频生成 AudioLM、MusicGen 语音合成、背景音乐、音效生成
- 视频生成 Sora、Wan 文生视频、图生视频、短视频剪辑生成
- 多模态通用模型(通才模型):GPT-4o、Gemini 2.5 Pro,同时兼容图文音视频跨模态输入输出
- 二者核心区别
- 输入输出限制:LLM 只处理文本;通用生成模型支持图像、音视频、文本多类数据。
- 能力定位:LLM 是通用模型下的文本专用分支;通用模型是覆盖全媒介的完整生成体系。
- 应用场景:LLM 主打聊天、文档、代码;通用模型可一站式完成绘图、做视频、配音、写文案全流程。
Token 完整详解
- 什么是 Token
- Token 是大模型的最小处理单位,AI 不直接识别汉字 / 字母,会把文字切分成小段 Token 再计算
- 中文规则:1 个汉字 ≈ 1.5~2 个 Token
- 英文规则:1 个单词 ≈ 1~2 个 Token
- 符号、空格、代码、图片描述、音频标签都会占用 Token
- Token 两大核心作用
- 计量计费
- 所有大模型 API 按 Token 收费:输入提问文字(输入 Token)+ AI 回答内容(输出 Token)合计扣费。
- 上下文窗口限制
- 模型有最大 Token 上限(上下文长度),代表单次对话能记住的全部内容总量。
- 例:1M 上下文 = 百万 Token 窗口;
- 痛点:百万级长上下文极易出现缓存失效—— 前文信息丢失、回答前后矛盾、逻辑断裂。
- 相关概念
- 上下文窗口:单次对话允许的总 Token 容量;
- 截断:Token 超出上限时,AI 会自动删掉最早的对话内容;
- 嵌入 Token:RAG 知识库中,文档向量化同样消耗 Token。
GPU
- GPU 全称图形处理器,最初是为电脑渲染游戏画面、图形图像设计的芯片。它内部有成千上万小计算核心,擅长同时并行处理大量简单重复运算。
- 训练、运行大模型时需要海量并行计算,现在 GPU 是 AI 最核心硬件载体,常见型号:NVIDIA A100、H100、RTX4090 等。
- AI相关
- GPU 是专门提供 AI 算力的核心硬件芯片
- 原本 GPU 是用来打游戏、渲染图形的,后来发现它超级擅长同时做几万个简单并行计算,刚好适配 AI 的计算特点
- CPU 适合复杂逻辑、串行干活(适合日常电脑办公)
- GPU 适合海量重复并行计算(天生适配 AI 训练 + 推理)
- LLM 大模型训练、Diffusion 图像生成、Sora 视频生成、音频生成、RAG 嵌入向量计算,全部依赖 GPU。
- 企业跑大模型 API、部署私有模型、运行 Agent、Vibe Coding 代码推理,全部靠 GPU 算力集群支撑。
- 国产模型、海外模型之所以迭代飞快(GPT5、Claude4.8、Qwen3),本质是算力堆出来的
算力
- 算力指硬件设备的计算能力,衡量单位常用 TFLOPS(每秒万亿次浮点运算) 简单理解:算力就是硬件干活的速度上限。
- 算力是AI 的干活能力,是支撑大模型「训练、回答问题、运行 Agent」的底层硬件计算能力
- AI 领域分为两种
- 训练算力:用来从零训练大模型,对算力要求极高;
- 推理算力:用户提问时运行模型给出回答,日常调用 API、本地跑模型都消耗推理算力。
- GPU 的核心价值就是提供高密度、高规格算力支撑 AI 模型运行。
- 有关AI
- 所有大模型(GPT、Claude、DeepSeek、Qwen)不是凭空诞生的,需要海量算力训练出来。
- 模型处理 Token、理解上下文、生成长文本、图片视频生成、RAG 向量计算、Agent 自主执行任务,每一步都在消耗算力。
- 算力越强:模型训练越快、回答速度越快、百万级上下文越稳、多模态生成越流畅。
- 算力不足:模型卡顿、推理慢、长文本缓存失效更严重、生成画质 / 音质变差。
- 简单总结:数据是原料,模型是算法,算力是动力。没有算力,所有 AI 模型都跑不起来
二者最简 AI 行业关系
- 算力 = 能力大小
- GPU = 提供算力的硬件工具
- GPU 是 AI 的发动机,算力是发动机的马力,所有大模型、多模态、Agent、RAG 技术,全靠 GPU 算力驱动
海外主流厂商 & 旗舰生成模型
- Anthropic 公司:Claude Opus 4.8,主打超长上下文、安全约束、代码与文档处理,推出专用 Claude Code(CC)代码智能体
- OpenAI 公司:GPT-5、GPT-5.5,行业标杆 LLM,早期 Codex 为专用代码大模型
- Google:Gemini 2.5 Pro,顶级原生多模态通用模型,图文音视频统一处理
- 补充特性:上下文窗口限制痛点
- 当模型上下文长度达到百万级 Token 时,极易出现缓存失效问题:长文本前后逻辑断裂、遗忘前文信息、回答前后矛盾,是超长文档场景核心性能瓶颈
国产主流大语言模型特点
- 深度求索 DeepSeek V4-Pro
- 核心优势:推理、代码场景成本可控,综合性价比突出,企业批量调用成本友好。
- 月之暗面 Kimi K2.6
- 核心优势:深度适配中文语境,中文日常对话流畅,超长文本读取、文档解析能力行业领先,适合阅读合同、小说、本地资料。
- Qwen3(通义千问 3)
- 提供完整开源版本,开发者可本地部署、二次微调,降低私有场景使用门槛。
各类生成模型分类总表
- 通用预训练生成基座(Seed)
- ├── 单模态生成模型
- │ ├── 文本生成 → LLM(GPT、Claude、DeepSeek、Kimi、Qwen)
- │ ├── 图像生成 → Diffusion(SD、Midjourney、Image2.0)
- │ ├── 音频生成 → AudioLM、MusicGen
- │ └── 视频生成 → Sora、Wan
- └── 多模态通用模型
- └── GPT-4o、Gemini 2.5 Pro(图文音视频统一处理)
API 调用基础逻辑(模型调用前置知识)
- 调用逻辑:所有云端大模型对外提供标准化 API 接口,程序、Agent、业务系统无法直接本地运行云端模型,必须通过接口远程请求。
- API Key:接口访问唯一密钥,相当于调用模型的 “通行证”。
- 获取流程:进入厂商开发者中心 → 注册开发者账号 → 账户充值(按量计费)→ 创建应用生成专属 Key。
- 安全管控:Key 具备权限区分,可限制可访问功能、调用额度、可操作资源,避免越权风险。
Agent 智能体技术(当前 AI 落地最高需求赛道)
- 核心定位
- Agent(智能体)是搭载大模型能力、具备自主规划、工具调用、循环执行能力的 AI 程序,也是各行各业落地需求最大的技术方向。
- 核心价值:代替人工完成整套复杂工作,核心目标 ——全方位提升人类工作效率,也是全球 AI 行业统一研发方向
- 通用 Agent 架构:通用 Agent + CC Switch 切换
- CC 即 Claude Code,代码专用智能体切换组件,可按需切换通用对话模式 / 代码编程模式
- 主流代码 Agent & 权限管控方案
- Claude Code(CC):Anthropic 推出的专业代码智能体
- Codex:OpenAI 初代代码专用大模型,代码 Agent 底层基座
- Hermes(小龙虾权限管控框架):负责 Agent 权限隔离,精准定义智能体可操作文件、可访问接口、可执行命令,限制高危操作,保障系统安全
- Agent 落地分类
- 通用 Agent:无行业限制,通用办公、通用代码、通用问答
- 行业垂直 Agent:针对特定行业 / 岗位定制(运维 Agent、办公 Agent、金融文档 Agent 等)
Vibe Coding 氛围编程(重点结合运维场景落地)
- 定义:氛围编程,依托 Agent + 代码大模型,通过自然语言描述需求自动生成、调试、优化代码 / 脚本,无需手动逐行编写
- 运维场景实际用途
- 批量生成 Shell 自动化脚本、容器编排 YAML、监控告警配置;
- 故障排查:自然语言描述报错日志,Agent 自动分析并输出修复命令;
- 批量运维工具开发、服务器巡检脚本、日志清洗脚本一键生成;
- 容器、K8s、ELK、数据库运维配置自动生成与优化。
RAG 检索增强生成 + 知识库体系(企业私有知识落地方案)
- 全称:Retrieval-Augmented Generation 检索索引生成
- 核心作用:解决大模型知识库截止、不具备企业内部私有知识的缺陷。
- 完整流程:
- 企业内部文档 / 资料 → 嵌入模型向量化处理 → 构建私有向量知识库索引 → 用户提问时先检索匹配内部资料 → 把检索内容投喂给 LLM → 模型结合私有资料给出精准回答
- 核心组件:嵌入模型(负责文本向量化,实现文档检索匹配)、私有知识库、向量数据库、LLM 大模型。
免费开发者工具:灵码
- 灵码平台提供免费大模型、Agent、代码调用服务,无充值门槛,但高峰期使用需要排队,适合个人开发者学习、测试、小型调试场景。
整体技术层级汇总
- 底层基座:Seed 通用生成基座、各类预训练单 / 多模态模型
- 中层能力:LLM 文本模型、扩散图像模型、音视频生成模型、嵌入模型(RAG 专用)
- 交互层:对话式 LLM 产品(豆包、千问、Kimi 等)
- 工程落地层:API 接口、RAG 私有知识库、Vibe Coding 氛围编程
- 上层应用层:Agent 智能体(通用 / 行业垂直 Agent,含代码 CC Agent)