2.linux之操作系统原理

一、CPU相关信息



1.CPU三大部件
    运算器:负责运算
    寄存器:数据暂存位置
    控制器:指令控制数据的存取过程
  1.1作用:内存是用16进制编址一个字节(单元)是8位,每个单元都有唯一地址标识,所以CPU有到RAM寻址能力,它们建立联系是靠
        一个芯片负责CPU电路与RAM电路建立关联关系
  1.2进程寻址:单进程寻址空间是3G,内核是1G,mysql就是单进程的它在32位系统上最多用2.7G内存,所以最好用64位系统
  1.3. 32位与64位有什么区别?
      32位相当于CPU出来32根线每条线有二种情况有电与无电共有2^32=4G种变化,它最多能找到4G个存储单元,所以32位最多只能
      理解4G内存空间,而64位相当于4G*4G上亿的内存空间,这只是寻址线路,但它还要把相应内存数据读出来,也需要电路,同时
      控制读写要发控制指令也需要电路?CPU电路是复用的,指令 读写与寻址都用这些线路,这些线路有控制位00--表寻址
      01-表读写 10--表发指令
    扩展:2^32种变化,一种变化能找到内存里的一个字节地址,4GB=4*1024MB=4*1024*1024KB=4*1024*1024*1024B(字节),内存
      的大小是按字节算的,4G内存是4*1024*1024*1024个字节
  1.4.PAE:物理地址扩展给32位寻址总线上加上4位能寻址2^36=64G--前提是内核支持用PAE技术,32位CPU只能跑32位系统,
      64位CPU二个系统都可以跑
  1.5.系统与CPU关系:只要内核是32位的无论内存本身有多大,单个进程所使用的内存空间小于3G,单进程服务是同用的,mysql
    是单进程多线程的,所以Mysql最好使用64位系统这样才会有更大的内存空间,而32位系统最多只能用2.7G内存
  1.6.CPU寄存器跟CPU一样速度完成数据存取,而内存比CPU频率慢很多,提供缓存

              

                        CPU
                          |----缓存1,比CPU慢比RAM快放的是RAM热区数据,当缓存满了,可用置换策略把数据置换出去
                          |    置换策略:1.LRU  2.MRU:varish用的,比LRU算法好,但要依赖其它标记位
                          |
                       北桥芯片                          
                          |
                          |
                          |
                           内存                      

                     注:程序局部性:(写程序按这个特性写能反应程序的快慢)
                               空间局部性:离的近的数据一并缓存
                               时间局部性:一般数据被访问很快才被访问
                     注2:多级缓存:
                            一级缓存:一级指令缓存,一级数据缓存
                            二级缓存与三级缓存:不区分类型
 
                      结构:
                            CPU1               CPU2          ----CPU
                        指令1  数据1       指令2  数据2         ----一级
                           缓存1              缓存2           ----二级共用一个CPU
                                     缓存1                    ----三级共用多个CPU

 

  1.7 RAM与缓存方法
    1.当RAM比缓存大太多时,RAM数据放在缓存上的有限,所以命中率很低--这种是把RAM数据放在缓存的任何位置叫直接映射
    2.直接映射效率低出现N路关联
      把RAM划片如划为三片,缓存也划三片,一一对应,最多可8路关联,这样就不会有些内存没有缓存用
    注:有缓存后CPU不在和内存直接打交道,CPU跟一级缓存打交道,对写操作而言,CPU会更新所有缓存及RAM及磁盘里的数据
      一起执行这叫--通写
      CPU在更新时只更新一级缓存数据后不会立即更新到RAM及磁盘上只有缓存的数据要丢弃时
        才能更新RAM及磁盘---回写(常用)
    3.CPU与其它设备关系:所有外围设备接进去后都是通过一个总线进到CPU的,如何区分它们?
      通过IO端口识别的,所有外围设备都有IO,IO端口也有65535个,任何一个IO设备通过IO总线接入到计算机总线时,必须
      申请一片连续端口,BIOS加电自检时,每个硬件都会CPU注册申请整个IO的一片连接端口,每次注册可能都不一样,要看先
      后次序,每个外部设备都有自己的控制器,用于将设备能理解的信号转换为在计算机总线上通信的信号,驱动就是驱动
      控制器指挥硬件工作的
      例:网卡来一个信号通过信号线路告诉中断控制器它通知CPU后,CPU根据IO端口到相应设备网卡上读取数据到RAM上,根据
      这个信号的急不急情况CPU可马上处理及等待处理,这是看进程的优先级来判定的
    4.有可能产生竞争的地方叫临界区,总线是由CPU使用的,它可以授权给各硬件的小CPU来控制,数据读取进内存的这条总线
      小CPU(DMA):直接内存访问,有中断进来CPU把信号读到RAM,它发现硬件上有DMA机制就会把内存中的一般连续内存并把相应
      的总线授权给DMA,CPU就退出DMA来控制数据的读取,DMA只能寻一部分内存,所以RMA前16M是给DMA用的,这是
      线性地址,它前还有1M是留给BIOS用的,
  1.8 CPU虚拟
    1.CPU能与其它硬件打交道可以运行各种程序,为防程序强占资源需要一个监控程序来调度它们---OS虚拟机
      一个独立运行程序需要系统资源:CPU时间、存储空间(内存)
    2.os虚拟机把CPU给虚拟成多个CPU来运行,cpu计算能力是按时间来算了,所以CPU按时间切处片完成虚拟,如CPU 1S走10圈
      有二个程序前0.5s给第一个程序后0.5s给后一个程序,不但的循环程序运行结果
  1.9 内存虚拟
    1.将内存按空间切片把内存按4K大小切割成各个存储槽(页面、页框)
      物理内存--页框4K
        |
      芯片---映射机制MUA
        |
      虚拟内存 -----按4K对应分配,每个进程认为自己都有4G可用
  2.0 IO设备的虚拟(在进程层次IO虚拟不需要专门做因CPU可直接交互)


二、系统工作及内核参数



  4.1:IO复用
    4.1.1:对于请求过多的服务器引出IO复用的概述
      1. nginx是一个高性能http服务器及反向代理服务器,它的出现为解决C10k问题:服务器并发连接达到10K以上引发众多问题
       问题1:多进程模型:早期http服务是多进程模型,一个进程响应一个请求,10000请求就10000个进程,进程切换成问题,一个80端口起10000个请

                          求,同时每进程里打开的文件数都是重复的
       问题2:单进程模型:工作在阻塞模型中,就起一个进程,一个请求一个请求的响应,很慢
           优化:线程,轻量级进程是进程内部的子单位,linux不支持原生态线程,一个进程多个线程内共用内的文件
        注:过程:一个请求进来访问主页,进程1看到请求是主页,进程1会向内核发起系统调用,这时进程1就变为不可中断睡眠状态,内核上去后会把IO上

                的文件拿到内核自己的内存里buffer与cache,加载完后然后把文件复制进程1的内存里,(由于内存空间是分页的,所以数据从硬盘上加到内存是一页一页的加载的,

                                      若一个页面是4K,那一次IO就是4K,但磁盘是磁盘块的块有1K 2K 4K的,可能读4个磁盘块也可能是2个或1个)---若一个线程一个请求,这个过程就变少了进程做完

                                      这个过程可供多个线程使用
        DMA:直接内存访问,是CPU的芯片,作用是多少个磁盘块加载到内存里CPU告诉DMA后由DMA指挥处理
        linux支持多少种类型线程库?如何切换?
       问题3:多进程多线程:多进程每个进程提供一部分线程,在同进程内部线程抢用资源情况变好
                                   缺点:进程与线程切换依然存在
       问题4:多线程:一个线程响应多个请求---说明一个线程要处理多个IO操作,一个IO完成时如何知道是哪个请求如何将等待的请求叫醒?
        一个进程一个请求叫醒进程就行,一个线程一个请求叫醒线程就行,一个线程多请求如何叫醒哪个请求?
          解决:请求就是通过网络进来的,都是通过TCP/IP协议连的,所以连接保存在内核里不管进程、线程还是请求的连接都保存在内核里,哪个连接处理到哪都由内核里的一个数据结构记录,哪个连接请求的IO完成内核就会通知对应的进程数据完成,将它从内核空间输出给用户空间--叫select(是一个系统调用,内核会为每个连接放个灯,数据完成就亮个灯把这个信息输出给对应的进程等但这个模型一次只能支持1024个请求,现在又有新年模型如下)---在线程模型下这些IO由进程完成,不用告知线程,所以用不用线程,IO都是由进程完成的,线程只是减少了内存的使用
          解决2:超过1024个请求后以上的系统调用就不适用了,一个线程响应多少请求,请求易阻塞,如一个线程有三个请求,第一个请求IO,线程会切换出去等,但第2.3个请求还在线程里要在cpu上跑,被切换出去了就跑不了就阻塞了,所以一线程多请求一个请求没完成线程也不能被阻塞它处理其它请求,所以一个线程多请求没有阻塞一说,阻塞只针对进程与线程当第一个请求完成后线程没有阻塞再等内核给它完成的消息,那线程如何知道第一个请求好了,IO完成了内核只会通知线程不会通知对应的请求?--这个由线程自己策略来维护,哪上请求好了就叫醒对应的请求在网络上实现通知对应请求,唤醒,在非阻塞模型通过内核中的多路IO复用机制来完成如select请求反应在本机上就是一堆套接字描述符文件,当某请求完成后就把这个描述符激活,让客户端取数据
一个线程多请求,多请求如何通知内核有二种方式:
                  方式1:同步通信:请求来了就通知内核一个个通知
                  方式2:异步通信:多请求来了线程统一告诉内核
          优点:磁盘IO是异步IO(AIO)---一个请求的IO不能让线程阻塞切换出cpu
          以上四个模型根据服务器压力自选某种模型
      线程在CPU运行时由于要读文件等操作因被别人占用不了但它的时间还有就要等,等分为
        忙等:通常用的是自旋锁,一会看下一会看下时间没耗完就占CPU不走---所以线程切换,资源抢用进程就负载不了
        闲等:切换出CPU让别人用


三、内核



  1.内核结构:
    在内核中内部有个链表,进程与进程之间在内核中内有一个数据结构管理(task-struct)是C语言的一个独立结构,这个文件整体
    结合叫进程描述符(保存进程元数据)启动多个进程,每个进程的描述符是有关联性的,在内核内通过双向链表,删除一个进程
    相应的进程描述符也要删除
    所有创建进程除了要分cpu、内存资源外还要在内核的内存空间中维护一个进程描述符文件,内包括所有进程信息
  2.进程切换:上下文切换
    进程A切换走的寄存器等数据会保存现场---保存在内核的进程描述符中(内存的内核中)描述符文件的大小是固定的,进程B上来
    是恢复现场的过程,把B的task-struct读到cpu上,上下文切换由内核完成所以每次切换都要先转移到内核模式再到用户模式
    所以cpu时间会被化分为进程时间%us与内核时间%sy
  3.linux支持抢占,优先级高的可抢低的(抢占时间是靠linux内部系统时钟tick,tick一次就可抢)
    linux有二个时钟:硬件时钟
    系统时钟:靠内部tick来记录时间,每次tick就是一次可抢的时钟中断
    注:红6.4后不再使用tick系统:只要tick就中断,需不需要用中断它都要中断耗电源
    引入了无tick系统完全靠中断(软中断--系统调用时从用户模式切到内核模式与硬中断),能让cpu深度睡眠
  4.进程类别
    1.交互式进程(I/O集密型):编辑器 vi word等要输入数据存入IO
    2.批处理进程(CPU密集型):守护进程,如nginx等需要大量cpu时间
    3.实时进程:必须能立刻响应---优先级高
    对PC机来说交互式进程应该优先级高,点键盘等要响应快,对服务器来说批处理优先级高它是等待请求来响应
    注:这个要靠调度器实现
      批处理进程时间片大优先级低
      IO密集型进程,时间短
  5.linux优先级有三类:
    1)实时优先级(1-99)数字越小优先级越低,通常跟内核相关,RT表1-99中的数据
    2)静态优先级:通常描述用户空间进程优先级100-139,数据越小优先级越高
      实时优先级高于静态优先级
    相关命令:
        ps -e -o class,amd|grep cms
      查看优先级:
        ps -e -o class, rtprio, pri, nice, cmd查看实时优先级
      调度类别 实时优先级 优先级 手动调整优先级 命令
      显示分析:CLS
        TS----SCHED_other调度器
        FF----SCHED_FIFD调度器
        RR----SCHED_RR调度器
    3)linux内核调度类别,它有三个调度器,用于调度不同优先级的进程
      1.实时优先级进程有二个调度器
        SCHED_FIFO:先进先出队列调度FIFO进程
        SCHED_RR:轮调,同一级别轮调,调度RR进程
      2.静态优先级
        SCHED_Other:按优先级调度
        红6还有二个调度器
        SCHED_BATCH
        SCHED_IDLE

  2.1,系统调用:当进程想打开硬盘上的一个文件进程没有权限,它要向内核申请内核就会把进程切换走自己到CPU,由它把数据读到
    物理内存再映射到线性地址上内核叫醒进程,内核就退出,内核会为每个IO准备缓存区数据先到内核缓存空间再进到
    进程的地址空间
  2.2,进程队列:如何排队切换到cpu有优先级,用到算法linux2.6后用到O(1)算法

 

四、系统启动流程


 1、linux启动流程:POST(加电自检,硬件内置的固化指令ROM(只读)映射到内存RAM)

---BIOS(读取BIOS中的配置看启动次序,先启动哪个硬盘(U盘 硬盘 网络等)上的操作系统)
 ---MBR(找到硬盘上找到硬盘的MBR当硬盘大于2T就不用MBR了就用gdp格式--MBR里有个程度bootloader,446,交给bootloader,
    它要识别内核所在的分区,但这时内核还没加载没有逻辑分区?只有硬的四个分区都没挂到根上,但根是系统进入用户空间的桥梁)
    所以启动内核时要给内核传一个参数,root(hd0,0)内核所在的硬分区 
    kernel /vmlinuz....(那个硬分区的内核位置) ro root=/dev/volo/root rhgb quiet(传给要启动内
    核的参数,内核在哪,根在哪 启动级别还有切换根用到的临时文件initrd /initrd.....) 1(启动级别,告诉内核启动第一个进程要进的级别)
---bootloader能访问的分区内核一定能访问所以内核一定要与initrd在一个分区,kernel与initrd都是bootloader装载的但initrd是由kernel使用而已 ---kernel加载选定的磁盘分区上的内核(装载驱动识别硬件(CPU 内存 各硬件),各种模块:文件系统进程管理 内存管理 驱动程序,内核必须要能驱动, 的了/所在的分区,否则启动不了/,驱动都在/lib/modules下要驱动/就要到这个目录找但没/就找不到驱动? 解决:在内核与根分区上加个层次让他专为内核提供根分区的驱动,但不同PC的根分区不同要有很多驱动,所以这个层次不是事先编译好的,它是由安装程序 提供的,安装程序把内核与/装进来时会知道/在哪,在安装快完成时它会收集内核访问根需要什么驱动并生成这个文件虚根内核如何访问这个文件?
在硬件级别上就能读到,虚根切换到真根上要把
/proc(内核映射启动时映射的) /dev(设备探测生成的) /sys(虚拟文件系统)
移到真根上这个文件:centos5:ramdisk(把内存当磁盘来用的)
---文件叫initrd certos6:ramfs---initramfs ---/sbin/init(由内核空间转换为用户空间,用户空间由于init管理,只有用到硬件时才切到内核) 注:/bin /sbin不能单独分区因为系统启动需要这二个目录下的文 内核必须识别根所在的分区,有的装在raid,有的是ide 有的是iscis,有很多所以内核要有各种驱动太多是单内核,太大可以做成 微内核,子系统坏了只有一个模块坏了 1.1内核结构 内核在设计上采用模块化设计有(1)核心.ko(2)外围模块(放在外的位置可动态加载).ko--由内核自己使用 ----初始化只是初始化核心 本身,内核会自动根据硬盘特性找对应的驱动模块加载进来,外围模块一般放在/lib/modules/内核版本号命名的目录/对应内核需要的各种模块 /lib/modules/2.6.32/kernel/ arch:与平台(cpu)相关的驱动cpu crypto:加密解密模块 drivers:驱动模块 fs:文件系统 mm:内存管理
net:网络管理 sound:声卡
1.2 bootloader的启动过程 1.2.1:bootloader是个程序,对不同操作系统是不一样的,它通常是由操作系统的安装程序提供的,但bootloader是位于MBR,MBR不属于任何操作系统 它是硬件级别的,安装程序会把bootloader装到选定的分区的MBR里,用来引导它所在的操作系统 1.2.2:linux的bootloader有二种 1.2.2.1:LILO:它不引导1024柱面以后的硬盘,所以它不支持8G以后的硬盘 1.2.2.2:(1)GRUB是装载BOOTLOADER中的程序,红5与6的GRUB版本不同,但MBR空间太小grub分为二段 stage1:装在MBR不是引导操作系统而是引导第二段 stage1.5:实现常见不同类型的文件系统在/boot/grub/ffs_stage1.5等等识别不同文件系统的 stage2:第二阶段真正引导操作系统,它放在内核的所在的父目录下/boot/grub/stage2,它是靠配置文件/boot/grub/grub.conf来
完成工作的它定义的背景图是
/boot/grub/splach.xpm.gz (2)配置文件内容/etc/grub.conf指向/boot/grub/grub.conf 全局属性: default=0:默认选哪个title,从上向下编号0,1,2...,设定默认启动的系统 timeout=5:等待用户选择title的超时时长单位s splashimage=(hd0,0)/grub/splash.xpm.gz:grub的背景图,linux的图片修改工具gimp(可以下一个装上后,能修改图片)
#gimp &--会出现图形页面 hiddenmenu:隐藏菜单,去掉就不隐藏前加#(隐藏意思是把编辑等菜单隐藏了,不能编辑等操作了 password --md5 $1$F*****************全局的 内核属性(个人理解:kernel与initrd文件都在/,实际这个hd0,0是挂在根磁盘的/boot目录下,这里的/vmlinuz,
/initrd指的是hd0,0这个盘的这个分区,所以装grub时要找个新的盘它必须要挂在*/boot上,*/boot代表的是根所在的盘,
在这个基础上对hd0进行安装grub,同时这个盘里要有内核核心、initrd 与grub的1.5与2阶段,1在MBR中 title red hat linux server(
2.6.18)---内核标题或操作系统名称,字符串,可自由修改 root (hd0,0)---内核文件所在的设备,对grub而言,所有类型硬盘都为hd,格式为(hd#,#)
#表第几个盘,第二个#表第几个分区
kernel /vmlinuz-2.6.18-308.el5 ro root=/dev/volo/root rhgb quiet ---内核文件路径及给内核的参数 initrd /initrd-2.6.18-308.el5.img(ramdisk或ramfs路径--是安装系统后自动生成的)
---因这时的文件系统还没起来所以找不到文件系统的根,所以它直接访问(hd0,0), 这个是boot有单独分区的情况下,如果boot没有单独的文件系统直接在根上,grub通过它的1.5阶段理解文件系统访问内核与initrd 就是/boot/vmlinuz-2.6.18-308.el5 /boot/vmlinuz-2.6.18-308.el5--这时根没有装载如何访问的根,
这个访问的不是根直接是根所在的磁盘分区,
/虽然没有装载但文件系统是真实写在磁盘上的,grub是根据它的1.5直接在磁盘分区
上读到文件系统的路径,它不是直接从根文件系统入口进来的 password
--md5 $1$F*****************(这个密码如何生成:#grub-md5-crypt输入密码后字符串复制过来):
给grup加密码,比如前写的单用户模式要进去需要这写这个密码,
以上title是进入grub的标记,到这个页面说明在跑1,1.5
2这几个阶段,这个页面可以进入编辑模式,编辑的也是grub.conf的内容,e就进编辑,写完后点b进入启动 (
3)命令小节: 系统重启:shutdown -r now:系统重启 查看运行级别:runlevel N:上一级别 3:当前级别 who -r:显示当前级别 init #:切换级别 查看内核版本号: uname -r uname -a:更详细 (4)如何安装grub 1.grub坏了:破坏MBR的前446字节不能破坏分区表 dd if=/dev/zero of=/dev/sda count=1 bs=400 sync:同步到磁盘 这时启动不了?如果启动要进救援修护 如果不启动如何修护?重装grub #grub grub>root (hd0,0)--内核在的分区 grub>setup(hd1)----安装stage1在哪个硬盘,在装时它会查这个盘里的第1.5与2阶段是否存在 grub>quit 2.安装grub(一个空磁盘没有第1.5与2阶段)--装所有的grub grub-install --root-directory=boot目录的父目录 [/dev/hda]--所有的sd都是hd eg:如/dev/hda1为空磁盘分区 mkdir /mnt/boot mke2fs /dev/hda1为空磁盘分区 mount /dev/hda1 /mnt/boot grub-install --root-directory=/mnt /dev/hda cd /mnt/boot---下有grub目录下有各种1.5与2阶段的文件但没有grub.conf,这个要手动创建 vi /mnt/boot/grub/grub.conf 再把内核核心与initrd复制过来把这个盘放在其它地方使用----这时内核能进来但没有init,要提供init与bash等就能
与人交互
3.grub.conf坏了如何启动?--这时有第一段无但没有配置文件找不到第二段了,启动时有grub提示符 grub>find (hd0,0)/---会打出内核与initrd的文件名字及位置 grub>kernel /vmlinuz2-2.6.18-308.el5---不给参数一般内核也能找到根 grub>initrd /initrd-2.6.18-308.el5.img grub>boot---启动 1.3 内核初始化过程 1.3.1:kernel初始化过程 1.设备探测 2.驱动初始化(可能会从initrd文件中装载驱动模块) 3.以只读挂载根文件系统(如果读写挂,程序出错会使系统崩,所以只读挂载只能读文件执行就行) 4.装载第一个进程init(PID=1) 1.3.2:kernel是如何装载模块的 1.核心:/boot/vmlinuz(linux是单内核) 内核模块:/lib/modules/version 2.装载模块命令: (1)内核装载了哪些模块:lsmod(列出模块) module模块名称 size大小 user by(被谁调用多少次) (2)modprobe mod_name:装载到内核核心的模块---不需指向模块路径只要指名就行 modprobe -r mod_name:卸载内核模块 insmod /path/to/mod_name:装载模块命令--指路径 rmmod mod_name:移除模块--不指路径 (3)modinfo mod_name:查看模块具体信息后直接跟模块名不能指路径 (4)由于模块间有依赖关系:depmod /path/to/mod_name---生成依赖关系表 若有个显卡没有驱动要下个源代码驱动手动编成.KO文件放在对应的路径下,且内核模块必须与内核完全匹配,内核为2.6.32-1驱动也必须
在2.6.32-1上编译 (5)内核模块能不能做到核心里,可以在编译时选择 1.不使用此功能 2.编译成内核模块 3.编译进内核核心 1.3.3:内核编译 yum grouplist查看Development Librares 与Development Toots这二个开发环境有没有装,装了才能编译程序
3.用户空间访问、监控内核的方式 用户空间与内核空间的机制:/proc /sys--来定内核参数,/proc /sys是伪文件系统,它们都有独立的分区 /proc:大多数是只读的,只有/proc/sys是可读写的,用户可以通过修改这里的参数来修改内核的应急特性 eg:/proc/sys/vm/swappiness--表是否使用交换内存 /proc/sys/vm/drop_cache---表清除buffers(数据源缓存) cache(数据缓存) echo 1> /proc/sys/vm/drop_cache--清除缓存 /proc/sys/kernel/hostname---主机名 echo www.magedu.com>/proc/sys/kernel/hostname /sys:某些文件可写可以修改硬件工作体制 设定内核参数的三种方式: 第一种:echo value>/proc/sys/to/somefile 第二种:命令sysctl sysctl -w kernel.hostname="www.magedu.com"(proc.sys省略) sysctl -w vm.drop_cache=1 以上只有暂时有效 第三种:永久有效不能临时有效vi /etc/sysctl.conf--rc#.d下的脚本会通过这个文件来设定内核参数 eg:net.ipv4.ip_forword=1---开启转发功能 vm.drop_cache=1 命令:sysctl -p--改配置后重读配置文件立即生效 sysctl -a:显示所有内核参数及其值 1.4 init启动过程 1.4.1:用户空间的所有程序初始化建立都要init完成---通过运行级别来定启动哪些服务,init定义启动哪个级别等用/etc/inittab来定 0:halt 关机 6:reboot:重启 1:单用户,不用密码 =s S single 2:多用户模式 3:多用户模式没有图形界面常使用 5:图形界面 6:未定义 1.4.2:红5/sbin/init(配置/etc/inittab)
红6以后用的都是/sbin/upstart(ubuntu开发的启动更快的Init,它是并行启动很多进程的
)后来又出现一个/sbin/systemd 1.红6在系统上upstart也叫init,配置文件也是/etc/inittab--但红6配置里只有一行默认级别,它是基于dbase来配置各服务间的通信 各子系统基于Ipc通信(进程间通信),各子系统可以由它统一管理,是基于事件来完成驱动的各子系统通信---是并行了,它有很多配置 文件不在是一个配置文件,路径如:/etc/init/*.conf---把inittab切成很多配置文件,每个文件都是按事件驱动方式编写的 该文件内容如下: start on startup:系统启动时启动 stop on runlevel:指定某级别会停止 console output pre start script for t in $(cat /proc/cmdline); do case $t in emergency) start rcS emergency break ;; esac done end script exec /etc/rc.d/rc.sysinit执行该脚本-------里面都是些执行的脚本命令等 2.红5配置文件inittab的详解 每行共有四个字段:标识符:运行级别:什么时候运行:执行进程 (1)id:3:initdefaule:---默认级别 (2)si::sysinit:/etc/rc.d/rc.sysinit--完成系统初始化,这是一个脚本 系统初始化是内核核外的系统初始化,系统初始化过程如下: 1.激活udev和selinux 2.使用交换分区 3.根据/etc/sysctl.conf文件来设定内核参数 4.设定时钟 5.装载键盘映射 6.设置主机名 7.根文件系统检测并以读写方式重新挂载 8.激活RAID和LVM设备 9.启用磁盘配额 10.根据/etc/fstab检查并挂载其它文件系统 11.清理过期锁和PID文件 脚本内容:系统起来后打印的登陆上的字幕在这里有定义 (3)l0:0:wait:/etc/rc.d/rc 0 l6:6:wait:/etc/rc.d/rc 6
wait:等待切入这个级别执行才执行
/etc/rc.d/rc是一个脚本能接受0-6级别里的内容是:eg 当参数是3时 for I in /etc/rc3.d/K*;do $I stop done----表/etc/rc3.d目录下的所有K开头的文件循环stop一下,K的数字越小越先执行 for I in /etc/rc3.d/S*;do $I start done----表/etc/rc3.d目录下的所有S开头的文件循环start一下,S的数字越小越先执行.一般先执行K再执行S开头的 其中所有的K与S开头的文件都指向/etc/rc.d/init.d/下的脚本(最终指向/etc/init.d),一个脚本相当于一个服务 这个目录下的脚本有什么特性: 特性1:至少要接受start|stop|restart|status这四个参数 特性2:这里的脚本都有二行,有这二行才能用chkconfig命令为此脚本创建S与K开头的链接 #chkconfig:级别 ##(S后的数字) ##(K后的数字) #description:说明此脚本的简单功能 eg: #chkconfig 345 81 8(在345级别下把这个脚本创建为S开关的链接,其它级别创建为K开头的,
后面的数字写在对应的S与K文件上)
eg:#chkconfig 345 77 22 #description:test service status() { if [ -e /var/lock/subsys/myservice ]; then echo "running" else echo "stopped" fi } usage() { echo "`asename $0` {start|stop|restart|status}" } case $1 in start) echo "starting" touch /var/lock/subsys/myservice;;---启动服务都会在/var/lock下建个锁文件 stop) echo "stopping";; rm -f /var/lock/subsys/myservice &>/dev/null restart) echo "restart";; status) status;; *) usage;; esca 注:#bash -n myservice.sh---看出哪一行执行有报错 特性3:chkconfig的使用(注这个脚本要放在/ect/rc.d/init.d下) chkconfig --list:查看所独立守护服务的启动设定 chkconfig --list service_name:看单个服务的启动设定 chkconfig --add service_name:加到服务列表中去 chkconfig --del service_name:删除这些链接文件不做守护进程 chkconfig --level # service_name on|off:指定哪些级别是开是关不用改脚里的值 若runlevel为-
时所有级别默认为K开头
(4)1:2345:respawn:/sbin/mingetty tty1---控制终端,登录前可以切换的终端 2:2345:respawn:/sbin/mingetty tty2 6:2345:respawn:/sbin/mingetty tty6 respawn:只要切换到2345级别一旦程序(mingetty)终止就再执行一次,
这里定义了能启动几个虚拟终端 (
5)x:5:respawn:/etc/Xll/prefdm ---图形终端 3./etc/rc.d/rc.local最后执行的一个脚本链接是S99最后一个执行的脚本 注:以上inittab的任务 (1)设定默认运行级别 (2)运行系统初始化脚本 (3)运行指定运行级别对应的目录下的脚本 (4)设定ctrl+alt+del组合键的操作 (5)定义UPS电源在电源故障/恢复时执行的操作 (6)启动虚拟终端 (7)启动图形终端 2.守护进程类型 2.1:独立守护进程 2.2:xinetd:超级守护进程 瞬时守护进程不需要关联至运行级别但他的超级守护进程要关联运行级别 把xinetd启动后用chkconfig --list 可以看到xinetd下有很多瞬时进程是on|off没有关联运行级别,如何让瞬时守护进程启来 chkconfig service_name on|off就能让其开启或关闭 3.防火墙 3.1:基本概述:工作在Linux的内核的网络防火墙 3.1.1:netfilter:是一个内核构架,起到防火墙的作用 iptables:生成防火墙规则将其加在netfilter上实现数据报文过滤,nat mangle等功能的工具 二主机通信实际是二进程通信如何标记:TCP--端口标记(0-65535) UDP---端口标记(0-65535) 0-1023只有管理员有权限使用
(所以这些端口的进程要是管理员) >5000是客户端使用的,所以客户端的端口都偏大,对Linux而言一切都是文件,每打开一个端口都是一个套接字文件 linux2.4以上用的是iptables/netfilter 3.1.2:发送报文时这些数据都要转换为能够通过网络发送的数据格式,常见有二种:1.文本格式 2.二进制格式 报文:外以太网帧---IP首部---TCP首部---数据 TCP的有限状态机 三次握手 1.客与服务才是关闭状态closed 2.客户主动连接SYN=1 ACK=0 状态:SYN_SENT 3.服被动打开套接字文件回 SYN=1 ACK= 1 状态:SYN_SENT 4.客回 SYN=0 ACK=1连接已建立 ESTABLISHD 四次断开 1.客与服务是ESTABLISHED状态 2.客发FIN=1 3.服发ACK确认 4.服发FIN断开 5.客发ACK确认 6.客与服是close状态 3.1.3:防火墙工作在网络/主机的边缘,数据报文进出的地方,对进出报文进行检查,并能根据事先定好的规则做出处理的一套组件叫防火墙
(网络:一个局域网通过路由器把所有主机接到网络可通过路由器限制,主机是通过网卡设备来限制),防火墙 可硬件可软件只是框架,规则(匹配标准,处理办法) 默认规则:开放ACCERT 写的规则用于堵,只能堵匹配到的规则写为DROP 关闭DROP: 写的规则用于通过,匹配到的通过规则写为ACCERT
3.1.4:防火墙的匹配标准及规则 (1)匹配标准 IP(源IP,目标IP) TCP(源端口 目标端口 标记位[SYN=1 FIN=0 RST=0 ACK=0]第一次握手 [SYN=1 FIN=0 RST=0 ACK=1] [SYN=0 FIN=0 RST=0 ACK=1]) UDP(源端口 目标端口) ICMP(icmp-type 报文类型) eg:对一个主机来说如果有二个网卡: 网卡1----内核----网卡2(请求来了网卡1打开帧首部看到IP发给内核) 对主机来说数据报文有三种流向:1.从外发进来的请求请求自己的进程----对应的钩子函数INPUT 2.自己的进程通过内核发出去的报文件----对应的钩子函数OUTPUT 3.转发的从外发来不是请求自己,是否帮忙转发给对应的地址上-----对应的钩子函数FORWARD 以上走哪条是根据目标IP来查本机的路由来实现的(路由决策)---在TCP/IP栈上工作 (2)规则写在钩子函数上(有五个函数) 1.除了以上的三个函数外还有二个函数 4.报文送到路由表前---POSTROUTING 5.报文经过路由决策之后,在网卡上排对正要发出去那刻--PREROUTING--这二个函数据不是用来实现拒绝/放行用户请求的,它是为了实现特殊手脚,
eg:地址转换NAT 内网(
172.16.100.6)----(172.16.100.7)路由(12.1.1.6)----外网(12.1.1.7100.6网关指向100.7,100.6访问1.7---源100.6 目标1.7,因100.6没有路由能力,若开转发功能100.6能访问1.7但1.7响应是回不来的,
网络上找不到100.6,若做地址转换 请求报文:在卡2要出去时变为源12.1.1.6 目标1.7 ---这个转换会记录下来响应时要还原回来通过Net自动还原 响应报文:在卡2要响应时变为 源1.7 目标1.6---过卡2时通过NET还原 (3)规则链上的功能 1.filte(过滤功能):INPUT OUTPUT FORWARD(链) 2.nat(地址转换功能):POSTROUTING PREROUTING OUTPUT(链) 3.mangle(报文拆开修改现封装):POSTROUTING PREROUTING INPUT OUTPUT FORWARD(链) 4.raw:不对报文进行修改:PREROUTING OUTPUT(链) (4)如何写规则:由匹配标准与处理动作组成 iptables [-t filte|nat|mangle|raw] command CHAIN(链) [num第几条规则] 匹配标准 -j 处理办法 1.command 1.1:管理规则命令 -A:附加一条规则,在链的尾部追加一条规则 -I INPUT NUM:插入一条规则,插入为第几条 -D CHAIN NUM:删除链上的每几条 -R CHAIN NUM:替换指定规则 1.2:管理链 -F CHAIN:清空指定规则链,若不写CHAIN表删除对应功能表所有链 -P CHAIN:指定链的默认策略 修改默认策略:iptables -P INPUT DROP -N CHAIN:自定义一个新的空链 -X CHAIN:删除一个自定义空链(不是空用-F清一下) 1.3:查看链上的规则 -L:显示指定表里的规则 -n:以数字格式显示主机地址和端口号 policy ACCEPT(默认策略) -x:显示计数器的精确值 -v:显示详细信息 --line-numbers:显示规则号码 eg:iptables -L n iptables -t filter -L -n---查filter表的所有链input output forwordf的规则 2.匹配条件 2.1通用匹配 -s:指定源地址(IP)也可指网络172.16.0.0/16 -d:指定目标地址(IP) -p:指定四层协议(tcp|udp|icmp) -i eth#:指定数据报文流入接口一般用在 INPUT PREROUTING FORWARD 上 -o eth#:指定数据流出接口一般用在 OUTPUT PREROUTING FORWARD 上 2.2:扩展匹配 2.2.1隐含扩展 -p tcp --sport port[-port]:源端口(可连续) --dport port[-port]:目标端口(可连续) --syn:第一次握手 -p icmp --icmp-type ping别人:8:请求报文 0:响应报文 别人ping进来:8:请求报文 0:响应报文 -p udp --sport port[-port]:源端口(可连续) --dport port[-port]:目标端口(可连续) eg:1.放行22端口 iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -p tcp --dport 22 -j ACCEPT(进来) iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0./16 -p tcp --sport 22 -j ACCEPT(出去) 2.本地回环设备 iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT 3.若http服务有木马,客户端用5001端口请求80端口,响应端口会从80出来,虽没请求木马,但木马会主动从80端口出去攻击其它已连接的
客户端,如何防? ip_conntrack:能追踪TCP UDP icmp,它根据IP报应进行追踪,请求与响应追踪它们的会话状态,多个客户端连会有不能的连接状态如何记录?
/proc/net/ip_conntrack:内核中的文件,保存当前系统上每个客户端与当前主机建立连接状态同时iptstate可查这些状态只显示tcp的 ip_conntrack模块iptables启动时装载的,最多存多少条目可看/proc/sys/net/ipv4/ip_conntrack_max----能保存多少连接的状态如果超过这些数据客户
端就连不上了,所以该模块一般不装载,但它依赖nat,如果in_nat模块装载了它就会被装载
2.2.2显示扩展 -m 扩展名称 扩展选项 1.结合ip_conntrack追踪会话状态 -m state --state NEW:新连接请求 ESTABLISHED:已建立连接 INVALID:非法连接请求 eg:iptables -A INPUT -d 172.16.100.7 -p tcp --dport 80 -m state --state NEW,ESTABLISHD -j ACCEPT iptables -A INPUT -s 172.16.100.7 -p tcp --sport 80 -m state --state ESTABLISHD -j ACCEPT iptstate查看所有连接状态其中TTL表超时时长,超过这个时长才能断开,默认TCP连接时长,这个时间太长影响其它请求,
   如何改这个时间
/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established 2.多端口扩展 -m multiport --source-ports 源端口 --destination-ports:目标端口 iptables -I INPUT -d ! 172.168.100.7 -p tcp -m multiport --destination-ports 22,21,80 -j ACCEPT 3.ip地址范围 -m iprange --src-range 172.16.1.1-172.16.1.5 --dst-range 172.16.1.1-172.16.1.5 4.连接处限定(公司只有一个网关能上网,所有用户都通过网关上网,每个用户打开连接不同,连接多耗尽带宽可限定并发连接数,
限定同时打开几个页面,后面的就打不开了)
-m connlimit --connlimit-above #:上限,前加!表取反 iptables -A INPUT -d 172.16.1.7 -p tcp --dport 80 -m connlimit ! --connlimit-above 2 -j ACCEPT
表每个客户端最多同时发起多少个请求
5.对Linux而言(网络IO调优),若有500个请求同时到达主机网卡使用什么方式解决?由于网卡带宽 内存 cpu都是有限的,
所以500请求同时进来处理不了会进行流量控制(实现工具用的是tc) 原理:令牌桶机制,这个桶里有500个令牌,请求拿到令牌后才能进这个桶里,而这个桶里放进内核处理的也要一批批处理,
多于500的那些都是请求超时了,而limit它不控制最大上限500
-m limit --limit 速率:单位时间允许多少进来 --limit-burst #:一起过来请求最多有多少 6.2.6.14内核才支持字符串 -m string --string pattern:包含这样字符串
3.处理办法:-j ACCEPT:通过 DROP:拒绝 REJECT:拒绝 DNAT:目标地址转换 SNAT:源地址转换 REDIREC:端口重定向 MASQUERADE:地址伪装 LOG:记录日志 --log-level:日志级别 MARK:给报文加标记
              (4)双网卡地址转发
iptables -t nat -I PREROUTING -i eth1 -d 172.16.5.100 -p   tcp --dport 9527 -j  DNAT --to-destination  10.1.1.173:9527
从eth1去向172.16.5.100:9527的流都通过10.0.0.173:9527转发出去,目标转发(在prerouting链上)
iptables -t nat -I POSTROUTING   -d  10.1.1.173 -p  tcp  --dport   9527  -j SNAT   --to   10.1.1.207
从10.1.1.173:9527来的流都能通过10.1.1.207发进来,(在postrouting链上)---eth1是192的地址,这里要开启ip_forward网关转发功能,才能把eth1的
流给到另一个网卡进行分配
4.以上写的规则写在/etc/sysconfig/iptables里,如何把写的规则写到这个文件里 
方式1.service iptables save
方式2:
/etc/rc.d/init.d/iptables save
方式3:iptables
-save>/etc/sysconfig/iptables.2013 iptables-restore</etc/sysconfig/iptables.2013
5.centos7关闭防火墙
(1)查看防火墙状态
systemctl status firewalld.service//active:running表开启
systemctl stop firewalld.service//关闭防火墙
systemctl disable firewalld.service//永久关闭防火墙

        2. centos7.0的启动流程

 

 

第一步:硬件启动阶段

这一步和CentOS6差不多,详细请看CentOS6启动流程(含详细流程图)

第二步:GRUB2引导阶段

从这一步开始,CentOS6和CentOS7的启动流程区别开始展现出来了,CentOS7的主引导程序使用的是grub2。

本步的流程:

1. 先加载两个镜像;

2. 再加载MOD模块文件,把grub2程序加载执行;

3. 接着解析配置文件/boot/grub/grub.cfg,根据配置文件加载内核模块到内存;

4. 之后构建虚拟根文件系统,最后转到内核。

在这里grub.cfg配置文件已经比较复杂了,但并不用担心,到了CentOS7中一般是使用命令进行配置,而不直接去修改配置文件了。

不过我们可以看到grub.cfg配置文件开头注释部分说明了由/etc/grub.d/目录下文件和/etc/default/grub文件组成。

一般修改好配置后都需要使用命令grub2-mkconfig -o /boot/grub2/grub.cfg,将配置文件重新生成。

第三步、内核引导阶段

这一步与CentOS6也差不多,加载驱动,切换到真正的根文件系统,唯一不同的是执行的初始化程序变成了/usr/lib/systemd/systemd

第四步、systemed初始化阶段(又叫系统初始化阶段)

CentOS7中我们的初始化进程变为了systemd。

本步的流程:

1. 执行默认target配置文件/etc/systemd/system/default.target(这是一个软链接,与默认运行级别有关);

2. 然后执行sysinit.target来初始化系统和basic.target来准备操作系统;

3. 接着启动multi-user.target下的本机服务,并检查/etc/rc.d/rc.local文件是否有用户自定义脚本需要启动;

4. 最后执行multi-user下的getty.target及登录服务,检查default.target是否有其他的服务需要启动。

注意:/etc/systemd/system/default.target指向了/lib/systemd/system/目录下的graphical.target或multiuser.target。

而graphical.target依赖multiuser.target,multiuser.target依赖basic.target,basic.target依赖sysinit.target,所以倒过来执行。

System概述(了解):systemd即为system daemon,是Linux下的一种init软件,开发目标是提供更优秀的框架以表示系统服务间的往来关系,

并依此实现系统初始化时服务的并行启动,同时达到降低Shell系统开销的效果,最终代替现在常用的System V与BSD风格的init程序。

与多数发行版使用的System V风格的init相比,systemd采用了以下的新技术:

A.采用Socket激活式与总线激活式服务,以提高相互依赖的各服务的并行运行性能;

B.用Cgroup代替PID来追踪进程,即使是两次fork之后生成的守护进程也不会脱离systemd的控制。

unit对象:unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、

保存的系统快照以及其他与init相关的信息。(也就是CentOS6中的服务器启动脚本)

(1)./etc/systemd/system/default.target

这是一个软链接,和默认运行级别相关

[root@localhost ~]# ll /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 37 11月 4 2019 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target

[root@localhost ~]# cd /lib/systemd/system/
[root@localhost system]# ls *.target
basic.target graphical.target kexec.target nss-user-lookup.target rescue.target shutdown.target sysinit.target
bluetooth.target halt.target local-fs-pre.target paths.target rpcbind.target sigpwr.target system-update.target
cryptsetup-pre.target hibernate.target local-fs.target poweroff.target runlevel0.target sleep.target timers.target
cryptsetup.target hybrid-sleep.target machines.target printer.target runlevel1.target slices.target time-sync.target
default.target initrd-fs.target multi-user.target rdma-hw.target runlevel2.target smartcard.target umount.target
emergency.target initrd-root-fs.target network-online.target reboot.target runlevel3.target sockets.target
final.target initrd-switch-root.target network-pre.target remote-cryptsetup.target runlevel4.target sound.target
getty-pre.target initrd.target network.target remote-fs-pre.target runlevel5.target suspend.target
getty.target iprutils.target nss-lookup.target remote-fs.target runlevel6.target swap.target
这里可以看到runlevel开头的target文件,对应着CentOS6的启动级别,不过一样是软链接,指向了同目录下的其他文件,也算一种向下兼容吧

[root@localhost system]# ll runlevel*.target
lrwxrwxrwx. 1 root root 15 6月 1 2020 runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 6月 1 2020 runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 6月 1 2020 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 6月 1 2020 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 6月 1 2020 runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 6月 1 2020 runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 6月 1 2020 runlevel6.target -> reboot.target

可以看到我的default.target与runlevel3.target指向的是同一个文件,可以看出我的默认运行级别是3。

(2)./usr/lib/systemd/system/

这个目录存储每个服务的脚本,类似CentOS6的/etc/init.d/

(3)./run/systemd/system/

系统执行过程中产生的脚本

(4)./etc/systemd/system/

类似于CentOS6的/etc/rc.d/rc#.d/SXX类文件的功能,管理员建立的执行脚本,大部分是软链接

posted @ 2021-03-25 16:12  xiong_Dana  阅读(167)  评论(0编辑  收藏  举报