Pit Viper

「欢迎来到水的国度,旅行者。希望你能享受这场‘演出’。」

Nginx

**简介:**Nginx由俄罗斯人开发,是一款开源、高性能的Web服务器、反向代理服务器、负载均衡服务器,其特点稳定、高性能、低能耗,其底层使用事件驱动+异步非阻塞I/O模型。

解释

事件驱动:Nginx 的 Worker 进程是单线程的,通过一个主循环监听所有 I/O 事件,如新连接、数据到达

I/O多路复用:使用高效的系统调用,如Linux的epoll,监听Socket

非阻塞I/O操作:Nginx进行I/O操作的时候,若数据未就绪,Worker会记录当前状态并转去处理其他请求,当数据就绪时通过事件回调继续处理。


Nginx重要文件目录

1
2
3
4
5
6
7
8
#主配置文件
/etc/nginx/nginx.conf
#自定义子配置文件目录
/etc/nginx/conf.d
#日志存放目录
/var/log/nginx
#日志切割文件
/etc/logrotate.d/nginx

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
vim /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

dnf clean all

dnf -y install nginx

部署静态Web网站

配置文件

1
2
3
4
5
6
7
8
9
10
server {
listen 2001;
server_name test01.com;

root /www/test01;

location / {
index index.html;
}
}

网站目录

1
2
3
4
mkdir -p /www/test01
vim /www/test01/index.html
chown -R nginx:nginx /www/test01
chmod -R 755 /www/test01

防火墙

1
2
firewall-cmd --permanent --add-port=2001/tcp
firewall-cmd --reload

测试

1
2
curl IP:2001
http://IP:2001

反向代理

作用在服务器端,Nginx接受请求后转发给后端服务器,最后将响应结果返回给客户端。

常用代理参数

1
2
3
4
5
6
7
8
9
#被代理服务器地址
proxy_pass http://xxxxxxx.????;
#Nginx的主机名,请求从哪个Nginx过来的
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;
#告诉服务器客户端使用的是什么协议
proxy_set_header X-Forwarded-Proto $scheme;

缓冲

作用:将服务器响应的数据放在内存中,等待请求中的数据处理完毕再返回给客户端,当缓冲区大小到达设定值后会写入临时文件内,防止客户端网速不好时拖慢服务器。

缓冲常用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#启用或禁用缓冲,on开启,off禁用,默认on
proxy_buffering on;
#单个缓冲区大小
proxy_buffer_size 4k;
#缓冲区数量和大小
proxy_buffers 8 4k;
#忙碌时缓冲区大小
proxy_busy_buffers_size 8k;
# 临时文件最大大小
proxy_max_temp_file_size 1024m;
# 每次写入临时文件的数据量
proxy_temp_file_write_size 16k;
# 临时文件目录
proxy_temp_path /var/nginx/proxy_temp;

缓存

作用:Nginx将响应数据保存在磁盘中,返回给客户端的数据优先从缓存中获取,提升网站性能,减轻服务器压力。

缓存常用配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#在http里指定缓存路径时间等
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m use_temp_path=off;
#解释
/var/cache/nginx:缓存数据存放路径
levels=1:2:定义缓存目录的层级结构
keys_zone=my_cache:10m:定义缓存名字和存储key的大小
inactive=60m:指定缓存项在不被访问情况下的保留时间
use_temp_path=off:禁用预缓存机制

#在server中配置,指定使用哪个缓存策略
proxy_cache my_cache; #上面keys_zone的值
#访问成功的数据保留时间
proxy_cache_valid 200 302 10m;
#404保留时间
proxy_cache_valid 404 1m;
#其他数据保留时间
proxy_cache_valid any 5m;

负载均衡

作用:将网络流量分发到多个服务器,以此来提高服务器的性能。

1
2
3
4
5
6
7
8
9
10
11
12
#在子配置文件或http中配置,和server标签是同级
upstream my_test{
server 服务器地址1;
server 服务器地址2;
...;
}

server {
location / {
proxy_pass http://my_test;
}
}

负载均衡策略

1
2
3
4
5
6
7
8
9
10
11
12
13
#不写默认是轮询,按顺序分发

#最少连接,将请求分发给当前连接数最少的服务器
least_conn

#IP哈希,将客户端IP作为哈希key的值,来自同一IP的请求总是发给同一服务器处理
ip_hash

#权重,能者多劳,尽可能的把请求分发给内存大的服务器,默认是1
weight=数值

#通用哈希,自定义哈希的key值,consistent仅对发生问题的服务器重新哈希解析
hash $request_uri consistent

问题

轮询和最少连接策略都可能造成来自同一客户端的请求分发到了不同的服务器上;

IP哈希当服务器宕机或者扩容的时候,会引发大量的路由变化,所有基于IP哈希策略的请求都要重新解析,导致大量缓存失效等问题;

健康检查

Nginx会检测后端服务器在指定周期内的失败响应次数,达到指定次数时,再下一个周期内都不会派发请求到该服务器上。

1
2
3
4
#指定周期时间,单位秒,默认10秒
fail_timeout=数值
#指定失败次数,默认1次
max_fails=数值

HTTPS配置

作用:对网络传输加密,实现互联网传输安全保护。

自定义生成证书

1
2
3
4
5
6
#生产密钥
openssl genrsa -des3 -out server.key 2048
#创建证书签名
openssl req -new -key server.key -out server.csr
#生成自签名证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
#crt文件
ssl_certificate 证书文件路径;
# .key文件
ssl_certificate_key 密钥文件路径
#禁用不安全协议
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#配置安全预设组合
ssl_ciphers HIGH:!aNULL:!MD5;
#指定密码文件所在路径,自定义文件,将密码填入即可
ssl_password_file 密码文件所在路径;
#设置SSL会话缓存,优化CPU,第一句缓存空间大小,第二句时间
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
}

TCP代理

作用:Nginx不仅可以代理HTTP请求,还可以作为TCP和UDP协议的代理,例如MySQL、Redis等服务。

注意点

1、在nginx.conf主配置文件中配置

2、配置块和http同级

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
stream {
upstream 自定义名称 {
server 服务器地址:端口;
server 服务器地址:端口;
...;
}
server {
listen 端口号;
proxy_pass 上面自定义的名称;
proxy_timeout 60s; #超时时间
proxy_connect_timeout 5s; #连接后端服务器的超时时间

}
}

扩展

在配置mysql的时候可以使用keepalive配置项来定义连接池空闲连接的数量;

连接池有一百个连接,可以指定始终开启的连接,这样就不用反复开关连接,减轻服务器资源的压力。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stream {
upstream 自定义名称 {
server 服务器地址:端口;
server 服务器地址:端口;

keepalive 8;
}
server {
listen 端口号;
proxy_pass 上面自定义的名称;
proxy_timeout 60s; #超时时间
proxy_connect_timeout 5s; #连接后端服务器的超时时间

}
}

重写

作用:用于修改或重定向URI。

第一种:return

1
2
3
4
#停止处理,返回状态码,或状态码加提示信息
return code [msg];
#重定向
return code URL;

第二种:rewrite

1
2
3
4
5
6
rewrite 正则表达式 替换目标 [标志位];

#标志位,重写后的处理流程,可选
last:停止当前rewrite处理,用重写好的URI重新搜索location块,相当于新请求,会重新执行匹配逻辑。

break:停止当前rewrite处理,不重新搜索location,继续执行后续指令,通常在location中使用。

Ansible

什么是ansible?

Ansible 是一款自动化运维工具,用于配置管理、应用部署、任务自动化和 IT 编排。

安装

1、安装epel-release仓库

1
2
3
4
5
dnf -y install epel-release

dnf clean all

dnf makecache

2、安装ansible

1
dnf -y install ansible

3、设置免密

1
2
3
4
5
6
7
8
#生成密钥
ssh-keygen

#将密钥发往目标主机
ssh-copy-id 目标IP地址

#测试
ssh root@目标IP地址

4、编辑ansible主机清单文件,指定要管理那些主机

1
2
3
4
5
6
7
8
#编辑控制节点的hosts文件
vim /etc/hosts
#最后添加
子节点IP 主机名

vim /etc/ansible/hosts
#最后添加
子节点主机名

5、测试是否能通子节点

1
2
3
4
5
6
#已配置免密
ansible 子节点主机名 -m ping

#未配置免密
ansible 子节点主机名 -m ping -u 用户名 -k
#输入密码

主机清单

想要控制哪些子节点,需要在 /etc/ansible/hosts 文件中指定

1、指定子节点用户名和密码

1
主机名	absible_ssh_user='用户名'	ansible_ssh_pass='密码'

2、当ssh端口不是默认22时,就需要配置端口

1
ansible_ssh_port='端口号'

3、指定分组,操作组时组下的成员都会执行指令

1
2
3
4
[组名]
子节点1
子节点2
...

4、组变量,当组内变量的值过多重复,就可以把相同的值拎出来,作为组全局变量,定义一次组内成员可以使用,例如有十台子节点的用户名都是root,密码都是000

1
2
3
4
[组名:vars]
ansible_ssh_user='用户名'
ansible_ssh_pass='密码'
...

5、子分组,将多个组合并成一个大组

1
2
3
4
5
[子组名:children]
组名
组名
组名
...

Ad-Hoc点对点模式

拷贝模块

1、拷贝文件到子节点

1
2
3
4
ansiable 组名或主机名	-m -a 'src=要拷贝的文件路径 dest=子节点存放文件的路径 owner=所属用户 group=所属组 mode=读写执行权 backup=yes'

#解释 backup=yes
如果目标子节点有这个文件并且内容不同,它会将原来的文件备份,把新文件覆盖在指定目录

用户模块

1、创建用户

1
ansible 主机名或组名 -m user -a 'name=用户名 state=present'

2、设置密码

1
2
3
4
5
#生成加密密码,然后赋值
echo "明文密码" openssl passwd -1 -stdin

#设置密码
ansible 组名或主机名 -m user -a 'name=用户名 passwrd="粘贴上面复制的加密密码"'

软件包管理

常用选项

1
2
3
-m:指定模块
-a:传递参数
-b:使用sudo权限

1、安装语法

1
ansible 组名或用户名 -m dnf -a "name=要安装的软件包名 state=present" -b

2、卸载语法

1
ansible 组名或用户名 -m dnf -a "name="要卸载的软件包名 state=absent" -b

3、更新所有软件包

1
ansible 组名或用户名 -m dnf -a "name='*' state=latest" -b

4、批量安装

1
ansible 组名或用户名 -m dnf -a "name=['1','2','3'] state=present" -b

服务模块

1、启动服务

1
ansible 组名或用户名 -m service -a "name=服务名 state=started" -b

2、停止服务

1
ansible 组名或用户名 -m service -a "name=服务名 state=stopped" -b

3、重启服务

1
ansible 组名或用户名 -m service -a "name=服务名 state=restarted" -b

4、重载服务,不重启

1
ansible 组名或用户名 -m service -a "name=服务名 state=reloaded"  -b

5、查看服务

1
ansible 组名或用户名 -m service -a "name=服务名" -b

6、设置开机启动

1
ansible 组名或用户名 -m service -a "name=服务名 enabled=yes" -b

7、禁止开机自动

1
ansible 组名或用户名 -m service -a "name=服务名 enabled=no" -b

文件模块

1、创建

1
2
3
4
5
#创建文件
ansible 组名或用户名 -m file -a "path=存放路径 state=touch" -b

#创建目录
ansible 组名或用户名 -m file -a "path=存放路径 state=directory mode=权限" -b

2、删除

1
2
ansible 组名或用户名 -m fiel -a "path=文件路径 state=absent" -b
ansible 组名或用户名 -m fiel -a "path=目录路径 state=absent" -b

3、修改

1
2
3
4
5
#修改所有者
ansible all -m file -a "path=路径 owner=用户名 group=组名 mode=0权限" -b

#修改权限
ansible all -m file -a "path=路径 mode=0权限" -b

4、将文件拷贝到子节点

1
2
#可以有多个文件,空格隔开
ansible all -m copy -a "src=文件路径 dest=子节点存放路径 owner=所属用户 group=所属组 mode=0权限" -b

5、从子节点下载到本地

1
2
#flat=yes 不创建主机目录结构
ansible all -m fetch -a "src=本地存放路径 dest=子节点存放路径 flat=yes" -b

6、修改文件内容

1
2
3
4
5
#覆盖
ansible all -m copy -a "content='内容' dest=文件路径" -b

#追加
ansible all -m lineinfile -a "path=文件路径 line='要追加的内容'" -b

收集子节点信息模块

1、查看子节点主机民

1
ansible all -m setup -a "filter=ansible_hostname"

2、查看IP地址

1
ansible all -m setup -a "filter=ansible_default_ipv4"

3、查看CUP信息

1
ansible all -m setup -a "filter=ansible_processor*"

4、查看内存信息

1
ansible all -m setup -a "filter=ansible_memory_mb"

5、查看磁盘信息

1
ansible all -m setup -a "filter=ansible_mounts"

6、查看操作系统版本

1
ansible all -m setup -a "filter=ansible_distribution*"

script脚本模块

1、将本地脚本传输到子节点主机运行

1
2
3
ansible 组名或用户名 -m script -a "脚本路径" -b
#带参
ansible 组名或用户名 -m script -a "脚本路径 参数1 参数2" -b

2、执行子节点已有脚本

1
ansible 组名或用户名 -m shell -a "脚本路径" -b

shell模块

远程执行Linux命令

1
2
#多个命令用 ; 隔开
ansible 组名或用户名 -m shell -a "Linux命令" -b

YAML剧本编写

语法格式

1
2
3
4
5
6
7
8
9
10
11
- hosts: 要执行剧本的子主机
tasks:
- name: 任务描述信息
模块: 要执行的命令
notity: 上面执行命令后,修改内容后执行名称
handlers:
- name: notity里定义的名称
模块: 要执行的命令

#notity和handlers解释
notity和handlers在第一次和内容没有发生改变时是不会执行的,只有内容发生了改变才会调用,例如:服务修改了端口号,子节点的配置文件里的端口号会被修改,但是服务不会重启,修改了端口号后服务需要重启才会生效,这时就可以用到 notity和handlers来重启!

执行

1、检查yaml剧本是否有语法错误

1
ansible-playbook 剧本文件.yaml --syntax-chech

2、列出剧本中的任务

1
ansible-playbook 剧本文件.yaml --list-tasks

3、列出要执行的子主机

1
ansible-playbook 剧本文件.yaml --list-hosts

4、执行剧本

1
ansible-playbook 剧本文件.yaml

角色组织

将yaml剧本内容分开写,实现解耦合、代码简洁、可复用。

标准角色结构

1
2
3
4
5
6
7
8
9
10
roles/
nginx/
├── tasks/
│ └── main.yml
├── handlers/
│ └── main.yml
├── templates/
│ └── nginx.conf.j2
└── vars/
└── main.yml

目录结构解释

roles:角色总目录名称

nginx:角色名称,什么服务用什么名称

tasks:定义任务

handlers:处理器,用于指定任务剧本里定义了 notity 的任务

templates:Jinja2模板文件,处理ansible内置变量和用户自定义变量

vars:决定自定义变量

main.yaml:主剧本,指定哪些子节点执行

Docker

什么是Docker?

Docker是基于操作系统层级、开源的虚拟化容器技术,用于快速构建、打包、分发、和运行应用程序,它可以将应用程序以及所需要的所有依赖打包进一个轻量级、可移植的容器中,并在任何支持Docker的环境中运行。

Docker能干什么?

1、快速部署应用程序

2、解决了环境问题,在自己机器上能跑,上线却报错

3、安全隔离,每隔容器独立运行,不会影响到其他容器运行

Docker核心组成部分

**镜像:**容器的模板,类似安装包,镜像作为模板可以创建多个容器,例如:我用tomcat镜像通过命令启动了一个tomcat1容器,我还可以再通过命令启动N个tomcat容器,一个模板创建多个容器,互不干扰。

**容器:**类似轻量虚拟机,共享主机内核,无需完成操作系统;独立运行,互不干扰;启动快、占用资源少,可以理解成一个简易的Linux系统。

**Docker引擎:**核心组件,用于创建和管理容器。


Docker安装

1、卸载删除docker,更新系统

1
2
3
4
5
6
7
8
9
10
dnf remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

dnf update -y

2、安装必备工具

1
dnf -y install dnf-plugins-core

3、配置软件源加速镜像地址

1
2
3
#清华大学镜像加速
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

4、安装docker

1
dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

5、启动、开机自启

1
2
3
4
5
6
7
8
#启动
systemctl start docker

#开机自启
systemctl enable docker

#是否安装成功
docker version

6、配置镜像加速,官方仓库在国外拉取镜像会很慢

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vim /etc/docker/daemon.json 

#清华大学地址
"https://docker.mirrors.ustc.edu.cn",

#填入以下镜像加速地址
{
"registry-mirrors": [
"https://mirrors.tencent.com",
"https://dockercf.jsdelivr.fyi",
"https://docker.jsdelivr.fyi",
"https://dockertest.jsdelivr.fyi",
"https://docker.m.daocloud.io",
"https://mirror.iscas.ac.cn"
]
}

7、 重启docker、测试

1
2
3
4
5
systemctl daemon-reload

systemctl restart docker

docker run hello-world

Docker命令

====== 镜像命令 ======

查看本机所有镜像

1
2
3
4
5
6
7
8
9
10
11
docker images [选项]
#常用选项
-a:显示所有镜像
-q:只显示镜像ID

#结果参数解释
REPOSITORY:镜像仓库源,名称
TAG:标签
IMAGE_ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小

搜索镜像

1
docker search 镜像名称

下载镜像

1
2
3
4
5
#下载最新版本
docker pull 镜像名称

#下载指定版本
docker pull 镜像名称:版本号

删除镜像

1
2
3
4
5
6
7
#镜像id可以写多个一起删除,空格隔开
docker rmi [-f] 镜像id

-f:强制删除,加了-f会忽略依赖检查,导致留下残留问题,慎用!

#删除所有镜像
docker rmi $(docker images -aq)

====== 容器命令 ======

创建容器并启动

1
2
3
4
5
6
7
docker run [选项] 镜像名称
#常用选项
--name:指定容器名字,区分容器
-d:后台运行
-it:交互模式运行,exit停止退出容器,Ctrl + p + q 不停止退出容器
-p:指定容器端口,最常用格式 真机端口:容器端口
-P:随机指定端口

查看容器

1
2
3
4
5
#查看正在运行的容器
docker ps

#查看所有容器
docker ps -a

删除容器

1
2
3
4
5
#删除单个容器,不能删除正在运行的容器,需要先停止
docker rm 容器id

#删除全部容器
docker rm $(docker ps -aq)

启动和停止容器

1
2
3
4
5
6
7
8
9
10
11
#启动
docker start 容器id

#重启
docker restart 容器id

#停止
docker stop 容器id

#强行停止
docker kill 容器id

====== 其它常用命令 ======

后台启动容器

1
2
3
docker run -d 镜像名
#问题:docker ps查看会发现该容器自动停止了
#原因:docker容器使用后台运行,就必须要有一个前台进程,如果没有docker会认为该容器没有提供服务自动停止了

查看日志

1
2
#根据容器id查看该日志,数字是几就查看几条日志
docker logs -th --tail 数字 容器id

查看容器中的进程信息

1
docker top 容器id

查看镜像元数据

1
docker inspect 镜像id

进入正在运行的容器

1
2
3
4
5
#进入容器会打开一个新窗口
docker exec -it 容器id /bin/bash

#进入容器不会打开新窗口
docker attach 容器id

从容器上拷贝文件到主机上

1
docker cp 容器id:容器文件所在路径 主机存放路径

Docker练习

====== 部署Nginx ======

1、安装

1
docker pull nginx

2、查看

1
docker imgages

3、运行

1
docker run -d --name nginx01 -p 801:80 nginx

4、查看

1
docker ps

5、进入容器查看

1
2
3
docker exec -it 容器id /bin/bash

whereis nginx

6、查看、放行宿主机801端口

1
2
3
4
5
6
7
8
#查看
firewall-cmd --list-port

#放行
firewall-cmd --permanent --add-port=801/tcp

#重新加载
firewall-cmd --reload

7、测试

1
2
3
4
5
#Linux下测试
curl http://192.168.10.20:801

#windows下测试
http://192.168.10.20:801

====== 部署Tomcat ======

1、拉取镜像

1
docker pull tomcat

2、查看

1
docker images

3、运行容器

1
docker run -d -p 8081:8080 --name tomcat01 tomcat

4、查看

1
docker ps

5、进入容器,查看

1
2
3
docker exec -it tomcat01 /bin/bash

whereis tomcat

6、宿主机放行8081端口

1
2
3
4
5
6
7
8
#查看
firewall-cmd --list-port

#放行
firewall-cmd --permanent --add-port=8081/tcp

#重新加载
firewall-cmd --reload

7、测试

1
2
3
4
5
6
7
8
9
#下载下来的镜像是被阉割过的最小环境,它的webapps目录下是空的,因为访问会404
#解决办法就是把webapps.dist目录下的内容复制到webapps下
cp -r webapps.dist/* webapps

#Linux下测试
curl http://192.168.10.20:8081

#windons下测试
http://192.168.10.20:8081

====== 部署MySQL ======

1、拉取镜像

1
docker pull mysql:8.0

2、查看

1
docker images

3、运行

1
2
3
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Yang@963214 --name mysql01 mysql:8.0 

#-e 表示设置环境,给root用户设置密码

4、查看

1
docker ps

5、进入测试

1
2
docker exec -it mysql01 mysql -uroot -p
#输入上面设置的密码

6、放行宿主机3306端口

1
2
3
4
5
6
7
8
#查看
firewall-cmd --list-port

#放行
firewall-cmd --permanent --add-port=3306/tcp

#重新加载
firewall-cmd --reload

7、使用Navicat测试

1
2
3
地址:192.168.10.20
用户名:root
密码:Yang@963214

Docker联合文件系统

UnionFS联合文件系统,它是Docker构建和管理容器镜像的核心技术之一,它允许将多个文件系统以层层叠加的形式组成一个单一同一的文件系统,所谓的分层简单理解就比如搭建一个环境,第一步安装了JDK环境比作第一层,第二步安装了mysql作为第二层,第三步安装Tomcat作为第三层,最后有联合文件系统一层层读取最后构建成一个完整的环境。

联合文件系统的优势

1、共享相同的基础镜像层,例如先下载了一个Tomcat 8,再去下载一个Tomcat 9时,当Tomcat 8里有Tomcat 9 所需要的层Docker就不会去再下载,而是拿Tomcat 8的过来直接用,只会下载缺失的层。

2、每一个层都有唯一的哈希标识,可以轻松退回到之前的层


Docker镜像都是只读的,当容器启动时,一个新的可写层会被加载到镜像的顶部,而这就是我们操作的地方,当我们将修改过的镜像打包时镜像已经被加了一层,比如一开始是6层,修改完打包完后就变成7层,新的那层就是我们所修改的东西。

提交自己镜像的命令

1
docekr commit -m="提交的描述信息" -a="作者" 容器id 为镜像取名:自定义版本

容器数据卷

什么是容器数据卷?

它是一个数据共享技术,通过目录挂载的方式可以完成Docker本地产生的数据同步到本地,完成数据持久化,这就是卷技术。

在启动容器的时候使用 -v 宿主机路径:容器内路径就可以实现挂载

实例1

要求:启动 rockylinux 将容器内的volume01挂载到宿主机的 /yzg/volumes/下,在容器中编写 hello.txt ,返回宿主查看

1、启动 rockylinux 容器并挂载

1
docker run --name yzg-linux01 -it -P -v /yzg/volumes:/volume01 rockylinux /bin/bash

2、进入volume目录创建 hello.txt

1
2
cd volume01
touch hello.txt

3、返回宿主机查看

1
ll /yzg/volumes

实例2

要求:启动数据库容器,将 容器内的mysql 配置文件挂载到宿主机 /yzg/mysql/cnof 目录下,将 mysql 工作目录挂载到 /yzg/mysql/data 目录

1
2
3
4
5
#msyql配置文件默认地址
/etc/mysql/conf.d

#mysql数据默认存放地址
/var/lib/mysql

1、启动并挂载mysql容器

1
docker run -d --name mysql01 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=Yang@963214 -v /yzg/mysql/conf:/etc/mysql/conf.d -v /yzg/mysql/data:/var/lib/mysql mysql:8.0

2、查看

1
2
3
ll /yzg/mysql/data

#看见mysql工作目录的文件和信息就成功了

匿名和具名挂载

具名挂载:不写宿主机挂载目录路径,而是为数据卷取一个名字(常用这种)

1
-v volume01:容器内地址

!!!====== 只要没指定宿主机挂载目录,全部默认在/var/lib/docker/volumes/下 ====== !!!

匿名挂载:顾名思义,挂载的时候不写宿主机地址或不取名,docker会自定为数据卷取名,但是很长

查看所有数据卷

1
docker volume ls

查看指定数据卷信息

1
docker inspect volume 数据卷名称

容器与容器之间实现数据共享

需要由第一个容器挂载到宿主机上,第二个容器再去挂载第一个容器;

第一个称为父容器,第二个称为子容器。

1
子容器 --volumes-form 父容器

1、父容器挂载宿主机

1
docker run -it --name linux01 -v /yzg/volumes/volume01:/home rockylinux /bin/bash

2、子容器挂载父容器

1
docker run -it --name linux02 --volumes-from linux01 rockylinux

DockerFile

什么是DocekrFile?

dockerfile是用来构建docker镜像的文件,一个命令参数脚本,通过docekrfile来生成一个镜像并发布发去。

DockerFile指令

注意事项

1、指令全部都是大写的

2、指令都是从上往下执行

3、#代表注释

4、每一个指令都会创建并提交一个新的镜像层

常用指令

1
2
3
4
5
6
7
8
9
10
11
12
FROM				#指定基础镜像
MAINTAINER #镜像作责信息,姓名+邮箱
RUN #镜像构建的时候需要运行的命令,想干点啥
ADD #将文件添加进镜像中,例如:tomcat压缩包
WORKDIR #镜像工作目录
VOLUM #挂载目录
EXPOSE #端口配置
CMD #指定容器启动时要运行的命令,只有最后一个会生效
ENTRYPOINT #类似CMD,区别是会追加命令而不是替换命令
ONBUILD #当构建一个被继承的DockerFile是就会运行ONBUILDD的指令,一个触发指令。
COPY #类似ADD,将文件拷贝进镜像中
ENV #构建的时候设置环境变量

编写DockerFiel构建自己的镜像

1、创建并编辑

1
2
3
4
5
6
7
8
9
vim rocyklinux-1.0

FROM rockylinux
MAINTAINER yzg-viper<3013237187@qq.com>
RUN dnf -y install vim
WORKDIR /home
EXPOSE 7777
CMD "======= yzg-viper ======"
CMD "====== Welcome to yzg-viper ======"

2、构建

1
docker build -f rocyklinux-1.0 -t yzg-rocky:1.0 .

3、查看是否构建完成

1
docker images

4、运行

1
docker run -it --name yzg-rocky01 yzg-rocky:1.0 /bin/bash

5、查看构建过程

1
docker history yzg-rocky:1.0

Docker网络

当安装完Docker的时候,Docker会提供一个叫Docker0的网卡,而docker0就相当于一个路由器一样管理docker中的网络,只要没有指定网络配置,在docker下都归docker0管,它使用的是 evth-pair 桥接技术,一段连着协议,一段相互连着,就是容器和docker0相连。

示意图

image-20250517151812698

容器与容器之间也可以互通,在容器启动的时候加上 容器A --link 容器B,这样A容器就能ping通容器B,但是反过来就不行,因为容器B里没有配置容器A的网络信息,现在已经不建议使用 –link 的形式来实现容器之间的相互通信,而是使用自定义网络

image-20250517143357647


Docker自定义网络

Docker自定义网络也叫容器互联。

doker创建网络命令语法格式

1
2
#--driver bridge表示桥接模式,可以省略不写,网段例如:192.168.0.0/16 
docker network create --driver bridge --subnet 网段 --gateway 网关 网络名字

启动容器时加入上面创建的网络

1
docker run --name 容器名 -it -p 宿主机端口:容器端口 --net 网络名字 镜像名:版本 

查看新建网络元数据

1
docker network inspect 网络名称

测试同网络下的容器互通

1
2
3
4
5
#tomcat默认使用精简版的Ubuntu作为基础镜像,没有ip addr 和ping等命令,需要进入容器内安装
apt-get update && apt-get install -y iputils-ping net-tools iproute2

#测试
docker exec -it tomcat01 ping tomcat02

Docker0和自定义网络的区别

Docker0默认只能通过ip访问;

而自定义网络即可以通过ip访问,又可以通过容器名访问。


网络联通

问题:在docker网络中,不同的网络怎么连通?比如,docker0网络的网段是172.168.0.0/16,而新建的网络网段是192.168.0.0/16,在docker0中的容器怎么访问到新建网络中的容器?

解决:在docker中使用 connect参数来解决这个问题,原理是将A网络中的容器加入到B网络中,在B网络中给加进来的容器赋一个本网段的ip地址,这样A网络中的容器就可以访问到B网络中的容器了!

简单理解就是一个容器两个IP,就好比阿里云的公网ip和本主机ip。

语法格式

1
docker network connect 网络名称 容器名称

Docekr网络常命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#查看所有网络
docker network ls

#创建自定义网络
docker network create --driver bridge 网络名称

#查看网络详情
docker network inspect 网络名称

#运行容器并加入网络
docker run --name 容器名称 -d -P --net 网络名称 镜像名:版本

#将容器加入到别的网络
docker network connect 网络名称 容器名称

#断开容器与网络的连接
docker network disconnect 网络名称 容器名称

#删除网络
docker network rm 网络名称

Docker Compose

什么是DockerCompose?

DockerCompose它是一款用于定义和运行多容器Docker应用程序的工具,使用YAML文件来配置应用服务,一个yaml配置文件管里N个容器。

服务:一个容器实例

项目:一组关联服务的集合,默认为目录名

顶级元素

1
2
3
4
5
name:指定项目名称
services:定义应用程序需的服务集合
networks:定义应用程序的网络,不存在则会创建
volumes:定义数据卷
environment:全局环境变量

常用配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
image:指定镜像
ports:指定宿主机和容器端口
volumes:指定容器数据卷挂载
networks:指定容器所使用的网络,网络必须已存在
environment:指定容器使用的环境变量
env_file:指定容器所使用的环境变量文件,与yaml主配置文同级目录
expose:指定对外暴露端口,提供给别的容量来访问

build:指定使用的自定义镜像,不能和image一起使用,二选一
context:build的子项,指定DockerFile文件的路径
dockerfile:build的子项,指定文件名,如果使用Docker默认的Dockerfile作为文件名的话,这一项可以不用配置

depends_on:指定服务所依赖的其它服务,确保依赖服务先启动
command:指定容器启动后将执行的命令

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
#启动所有服务,-d后台启动
docker compose up
#停止并删除容器、网络
docekr compose down
#查看运行中的镜像
docker compose ps
#查看日志,-f实时跟踪
docekr compose logs
#重新构建镜像
docker compose build
#进入容器
docker compose exec 容器名称

部署MySQL实战

1、目录结构

1
2
3
yzg_mysql/
├── docker-compose.yaml
└── .mysql_env

2、编辑.mysql_env文件,数据库密码

1
MYSQL_ROOT_PASSWORD: 000000

3、编辑docker-compose.yaml,默认文件名就使用这个,不用这个会找不到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#指定项目名称
name: yzg_mysql
#定义网络
networks:
net1:
#定义数据卷
volumes:
db_data:
#定义容器
services:
mysql01:
image: mysql
ports: ["3306:3306"]
volumes:
- db_data:/var/lib/mysql
env_file:
- .mysql_env
networks:
- net1

4、运行

1
docker compose docke-compose.yaml

5、navicat测试

1
2
#用户名root
#密码000000

Linux基础

什么是Linux?

Linux它是一款基于C语言开发的操作系统内核;其主流发行版有Ubuntu、RedHat、Debain、RockyLinux,

这些发行版基于Linux系统内核构建成不同的操作系统版本,Linux系统一般作为服务器操作系统使用。

特点:支持多用户、多任务、多线程,稳定性、安全性和自由度高。


目录结构

在Linux系统下万物皆是文件,使用Linux几乎都是在根文件打交道。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/:根目录,所有目录和文件的起点

bin:存放二进制可执行文件,基本命令

boot:存放启动文件,内核文件、引导加载器

dev:设备文件,硬件和虚拟设备的接口文件

etc:存放系统和应用程序的配置文件

home:用户主目录,存放普通用户的家目录

lib/lib64:存放系统所需的共享库

media:自动挂载可移动设备,如U盘

mnt:临时手动挂载文件系统,如额外磁盘

opt:第三方或大型软件的安装目录,如IDE

proc:虚拟文件系统,存放内核和进程信息

root:root用户家目录

run:存放系统运时的临时文件,重启即失效

sbin:存放系统管理员命令

srv:存放服务相关的数据

tmp:存放临时文件

usr:存放用户级应用程序和文件

var:存放经常变化的文件,如日志

系统常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#查看Linux发行版本
cat /etc/os-release

#查看Linux内核版本
uname -r

#查看当前用户
whoami

#立刻关机
shutdown -h now

#指定分钟关机
shutdown -h 数字

#重启
reboot

#注销
logout

#将内存中的数据同步到磁盘中,重启和关机前先执行这条命令,方式数据丢失!
sync

vim

什么是vim?

vim它是一款功能强大、跨平台的文本编辑器。

vim的三种模式

普通模式:默认模式,从其它模式切换按Esc键,用来执行命令

插入模式:按 i 进入插入模式,可以对文件编辑

命令行模式:在普通模式按 : 冒号进入,用来执行保存、退出、搜索、等操作

安装

1
yum -y install vim

快捷键

快捷键 作用
yy 拷贝当前行,5yy向下拷贝5行,按p粘贴
dd 删除当前行,5dd向下删除5行
/关键字 根据关键字在文件中查找内容,回车查找,n查找下一个
set nu 显示行号
set nonu 不显示行号
shift+g 跳转文件最末尾处,按56接着按shift+g可以快速跳转56行
gg 跳转文件首行
u 撤销上一次输入动作

忘记root密码

1、在开机动画页面按e

2、找到以linux16开头的段落,在末尾的UTF-8后面加上init=/bin/sh,再按ctrl+x键进入单用户模式

3、进入单用户名模式后输入,mount -o remount,rw / 回车

4、再次输入passwd后回车,输入第一次新密码后回车,再次输入新密码确定

5、再次输入touch /.autorelabel回车

6、最后输入exec /sbin/init回车,系统重启输入新密码即可


文件目录管理

1
2
3
以 d 开头的是目录
以 - 开头的是文件
以 l 开头的是软连接,类似快捷方式

文件目录常用命令

命令 作用 语法
pwd 显示当前所在工作目录绝对路径 pwd
ll 以列表形式查看当前目录内容信息 ll
ls -a 查看当前目录所有内容信息,包括隐藏文件 ls -a
tree 以树状显示目录结构 tree [目录名称]
cd 目录之间切换 cd [目录路径]
mkdir 创建目录,加 -p 可以创建多级目录 mkdir [目录名称]
rmdir 删除空目录 rmdir [目录名称]
rm 删除指令,-r 递归删除,-f 强制删除不提醒 rm -rf [目录或文件名称]
touch 创建空文件 touch [文件名]
cp 拷贝文件或目录,加 -r 可以递归拷贝 cp [源文件] [目标路径]
mv 重命名或移动文件或目录 mv [源目录或文件] [目标路径]
cat 查看文件内容,加 -n 可以显示行号 cat -n [文件名]
less 分页查看文件内容 less [文件名]
echo 输出内容到控制台 echo [输出内容]
head 显示文件开头部分内容,加 -n 数字 可以指定显示几行 head [文件名]
tail 显示文件末尾部分内容,加 -n 数字 可以指定显示几行 tail [文件名]
tail -f 实时最终文件更新内容 tail -f
> 输出重定向,会覆盖原有内容
>> 输出追加
ln -s 软链接,相当于创建一个快捷方式 ln -s [源文件或目录] [软链接名]
history 查看历史命令,!编号 可以执行指定编号的历史命令 history
du -h 路径 查看指定路径目录大小,不加路径查看所在目录 du -h 路径
ll -h 路径 查看指定路径文件大小,不加路径查看所在文件 ll -h 路径

用户管理

用户管理常用命令

命令 作用 语法
useradd 添加用户 useradd [用户名]
passwd 修改密码 passwd [用户名]
userdel 删除用户,加 -r 连同家目录一起删除 userdel [用户名]
id 查看用户信息 id [用户名]
su 切换用户 su [用户名]
who am i 查看当前用户登录信息 who am i
usermod -l 修改用户名,不会自动更改用户的家目录名 usermod -l [新用户名] [旧用户名]
usermod -d -m 修改用户名后,将旧家目录移动到新家目录 usermod -d /home/[新用户名] -m [新用户名]

用户组管理

用户组管理常用命令

命令 作用 语法
groupadd 新增组 groupadd [组名]
groupdel 删除组,组下有成员则不能删除 groupdel [组名]
usermod -aG 追加用户到,不离开原有组 usermod -aG [组名] [用户名]
gpasswd -a 添加用户进组,推荐使用 gpasswd -a [用户名] [组名]
gpasswd -d 将用户移出组,推荐使用 gpasswd -d [用户名] [组名]
groupmod -n 修改组名 groupmod -n [新组名] [旧组名]
groupmod -g 修改组GID数字表示 groupmod -g [新GID] [组名]
groups 查看用户所属的组 groups [用户名]

搜索查找命令

在Linux中一般使用find命令在进行查找操作。

**语法:**find <搜索范围> <选项>

选项:-name按文件名查找;-user按用户名查找;-size按大小查找


压缩解压命令

第一种zip和uzip

需要安装

1
2
yum install -y zip
yum install -y uzip

**zip压缩语法:**zip [选项] 压缩包名称.zip 要压缩的文件或目录

常用选项

-r:递归压缩子目录

-q:不显示压缩过程

-e:加密压缩,设置密码

**uzip解压语法:**uzip [选项] 压缩包名称.zip

常用选项

-d:指定解压目录

-l:查看压缩包内容不解压

-o:强制覆盖已存在的文件

-q:不显示解压过程

-P:直接提供密码,不推荐,推荐进行交互

第二种tar命令

压缩:tar -zcvf 压缩包名称.tar.gz 要压缩的文件或目录

解压:tar -zxvf 压缩包名称.tar.gz

常用选项

-c:创建归档文件

-v:显示详细信息

-f:指定压缩后的文件名,必须放在最后

-z:打包同时压缩

-x:解包.tar

-C:指定解压或压缩后存放目录


文件权限管理

1
2
3
4
5
6
7
8
9
#权限
r=4:代表可读
w=2:代表可写
x=1:代表可执行

#字母代表
u:代表文件拥有者
g:代表同组内
o:代表其他组

常用命令

1
2
3
4
5
6
7
8
9
10
11
#数字形式语法
chmod [权限数字] 文件名

#字母形式语法,有 + 有 -
cmoud 字母代表+权限字母

#修改文件拥有者,-R 可以递归生效
chown [选项] 用户名 文件名

#修改文件所属组,-R 可以递归生效
chgrp [选项] 组名 文件名

任务调度

设置系统在指定时间执行指定命令或程序

第一种:crontab命令,到了指定时间会执行

语法:crontab [选项]

常用选项

1
2
3
4
5
-e:编辑定时任务

-l:查看定时任务

-r:删除定时任务

定时任务时间规则

1
2
3
4
5
6
7
8
9
10
11
12
13
#符号代表的意思
*:代表任何时间
,:代表不连续的时间
-:代表连续时间的范围
*/n:代表每隔多久执行一次


#每个 * 代表的含义
第一个 * :代表一个小时中的第几分钟
第二个 * :代表一天中的哪个小时
第三个 * :代表一个月中的几号
第四个 * :代表一年中的几月
第五个 * :代表一周里的星期几,0和7都代表星期日

crontab定时任务例子

要求:编写脚本打印当前时间后追加到指定文件内

1、编写shlle脚本

1
2
3
vim my.sh

date >> /home/yzg/showking/crontab.log

2、设置执行权限

1
chmod u+x my.sh

3、编辑定时任务

1
2
3
crontab -e

*/1 * * * * /home/yzg/showking/my.sh

4、查看定时任务

1
crontab -l

5、等待时间到执行后查看

1
cat crontab.log

第二种:at命令

at定时任务只会执行一次,且需要atd守护进程每60秒检查作业队列,有作业时检查作业运行时间,当指定时间与当前时间匹配后会执行at定时任务;

编辑at定时任务会进入交互模式,按 Ctrl+d 才可以保存退出交互模式

查看atd守护进程是否运行

1
ps -ef | grep atd

安装启动atd守护进程

1
2
3
yum -y install at

systemctl start atd

at定时任务时间规则

1
2
3
4
5
6
7
8
9
10
11
12
13
完整时间:mm:ss YY-MM-DD
例子:at 18:40 2025-05-05

上午、下午:am代表上午,pm代表下午
例子:at 8am 或者 at 9pm

在当前时间基础上加时间:now + 数字 时间单位
now:代表当前时间
时间单位:minutes(分钟)、hours(小时)、days(天)、weeks(星期)
例子:at now + 2 minutes

今天或明天:today(今天)、tomorrow(明天)
例子:at 9am tomorrow

at定时任务实例

要求:在当前时间两分钟后执行查看指定文件命令


磁盘操作

在Linux下一切皆为文件,所以磁盘表达的方式和windows有所不同,在Linux一块磁盘可以分为多个分区,分出来的子分区通过mount命令挂载到某个指定目录,让子分区和目录产生关联,访问目录就是访问该分区。

查看磁盘情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#查看挂载情况
lsblk

#详细查看挂载情况
lsblk -f

#查看磁盘使用情况
df -h

#查看指定目录
df -h 目录路径

#df命令常用选项
-s:指定目录占用大小总汇
-h:带计量单位
-a:将文件也显示
--max-depth=数字:子目录深度
-c:列出明细的同时,增加总汇

fdisk命令操作磁盘

1、分区

1
2
3
4
5
6
7
fdisk /dev/sd?   #?代表具体是哪块硬盘,例如sda,sdb....

m:显示命令
p:显示磁盘分区
n:新增分区
d:删除分区
w:写入并退出

2、格式化

1
mkfs -t ext4 /dev/sd??   #ext4表示分区的类型

3、临时挂载

1
mount /dev/sd?? [挂载目录]

4、卸载分区

1
umount /dev/sd?? 或者 umount [挂载目录]

5、删除分区

1
parted /dev/sd? rm 分区号

parted命令操作磁盘(推荐使用)

MBR与GPT:它们都是分区时所要选的分区格式

MBR:老式的分区表类型,支持最大容量为2TB,最多支持4个分区,引导记录存储在第一个扇区,不推荐。

GPT:新型分区表类型,支持大于2TB的硬盘,分区数量几乎不受限制,采用全新结构,更安全、快速,推荐使用。

查看磁盘分区表情况

1
parted /dev/sd? print

创建分区表

1
parted /dev/sd? mklabel gpt

注意:这条命令会格式化清楚指定磁盘上的所有数据!!!

创建子分区

1
2
#语法:parted /dev/sd? mkpart 分区类型 文件类型 容量启示位置  容量结束位置
parted /dev/sdb mkpart primary ext4 1MiB 10GiB

修改子分区容量大小

注意:尽量是由小改到大,避免大改小,大改小数据可能会丢失!!!

1
2
#语法:parted /dev/sd? resizepart 分区号 新的结束位置
parted /dev/sdb resizepart 1 15GiB

临时挂载

1
mount /dev/sd?? 挂载目录路径

永久挂载,fdisk命令通用

1
2
3
4
5
#编辑/etc/fstab文件
vim /etc/fstab
#添加.二选一
第一种方式:UUID=分区的UUID [挂载目录] 分区文件类型 defaults 0 0
第二种方式:/dev/sd?? [挂载目录] 分区文件类型 defaults 0 0

立即生效

1
mount -a

卸载分区命令

1
umount /dev/sd?? 或者 umonut 挂载目录路径

删除分区命令

1
parted /dev/sd? rm 分区号

主机名Hosts映射

应用场景:当需要通过ping主机名的方式测试网络是否互通时,可以通过编辑Hosts文件来记录IP和主机名的映射关系,ping 主机名就等同于ping IP。

查看主机名

1
hostname

修改主机名

1
2
3
4
5
6
7
#第一种方式
hostnamectl set-hostname 新主机名

#第二种方式
vim /etc/hostname

#修改后需要重启才能生效

配置主机名与IP映射关系

1
2
3
4
5
#编辑hosts文件
vim /etc/hosts

#最后添加
IP 主机名

**知识扩展:**这里用到了DNS技术,DNS中文意思是域名系统,是互联网上作为域名和IP地址相互映射的一个分布式数据库;例如现实生活中的信息数据库,记录人的名字和身份证号。

DNS技术简单解析

案例:用户在浏览器输入www.baidu.com

首先请求会在浏览器缓存中去找该域名的解析IP地址,找到就调用;

没有找到则会进入本地的DNS缓存找,找到就调用;

没有找到则会进入本机的hosts文件里找,找到就调用;

没有找到则会去配置的DNS服务器里找,找到就调用,没有找到则返回该域名无效。


进程管理

在Linux中每一个执行的程序都称为一个进程,每一个进程都会分配一个ID号,也叫pid进程号;

每个进程都可能以两种方式存在,前台和后台,前台进程运行时通常都会占据屏幕可以进行交互;

后台进程则不会占据屏幕,但它已经开始工作了,例如 MySQL Tomcat,一般系统的服务都是以后天的方式存在且会常驻在系统中,直到关机才结束。

程序和进程的关系

程序是指没有通过命令运行加载进内存的源代码文件,静态的;

进程是指程序通过命令运行加载进内存开始工作后,动态的。

查看进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#查看当前终端的所有进程信息,不会显示父进程的ID
ps -aux
#常用选项
-a:显示所有进程
-u:以用户的格式显示进程信息
-x:显示隐藏的进程信息

#以全参数的形式查看所有进程信息,会显示父进程的ID
ps -ef

#分页查看进程信息
ps -aux | more
ps -ef | more

#过滤查看指定进程信息
ps -aux | grep 进程名称
ps -ef | grep 进程名称

进程参数解析

参数 解释
USER 进程执行用户
PID 进程号
PPID 父进程号
%CPU CPU使用占比
%MEM 物理内存使用占比
VSZ 虚拟内存大小(KB)
RSS 物理内存大小(KB)
TTY 终端
STAT 运行状态
TIME 占用CPU时间
CMMAND 进程名,执行该进程的指令

**运行状态分类:**s 表示休眠,r 表示运行中,d 表示短期等待,z表示僵死(进程死了内存还没释放,需要手动释放),t 表示被跟踪或被停止。

终止进程

1
2
3
4
5
#只终止本进程,-9选项表示强制执行
kill [选项] 进程号

#终止本进程以及子进程
killall 进程名(如nginx)

服务管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#启动
systemctl start 服务名称

#停止
systemctl stop 服务名称

#重启
systemctl restart 服务名称

#开启自启
systemctl enable 服务名称

#取消开机自启
systemctl disable 服务名称

#查看所有服务开机自启状态
systemctl list-unit-files

#查看指定服务名开机自启状态
systemcatl is-enabled 服务名

防火墙管理

在个人学习中可以随意关闭防火墙,在工作环境中禁止关闭防火墙!!!

防火墙常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#查看已放行的端口
firewall-cmd --list-port

#放行端口
firewall-cmd --permanent --add-port=端口号/协议

#关闭端口
firewall-cmd --permanent --remove-port=端口号/协议

#修改立即生效
firewall-cmd --permanent --reload

#查看指定端口是否放行
firewall-cmd --query-port=端口/协议

#启动防火墙
systemctl start firewalld

#关闭防火墙
systemctl stop firewalld

#开机自启
systemctl enable firewalld

#取消开机自启
systemctl disable firewalld

动态监控

动态监控使用 top 命令来执行,top与ps命令很相似都是用来显示正在执行的进程,它们两个最大的不同就是top命令在执行一段时间可以更新正在运行的进程。

语法格式

1
2
3
4
5
6
top [选项]

#常用选项
-d:指定top命令几秒更新一次,默认3秒
-i:不显示闲置或僵死进程
-p:通过指定进程ID监控某个进程状态

交互操作指令

1
2
3
4
5
6
P:以CPI使用率排序
M:以内存使用排序
N:以PID排序
u:输入用户名动态监听指定用户情况
k:输入对应进程号终止该进程,需要root权限
q:退出

网络监控

在Linux中使用netstat和ss命令来监控网络状态,netstat命令已经逐渐被淘汰,现在推荐是ss命令。

语法格式

1
2
3
4
5
6
7
8
9
10
11
12
ss [选项]

#常用选项
-t:显示TCP连接
-u:显示UPD连接
-l:监听中的套字节
-n:禁用域名解析
-p:显示进程信息
-a:显示所有
-s:统计摘要
-o:显示计时器信息
-4/-6:仅IPv4/IPv6

输出参数解析

1
2
3
4
Netid:协议类型
State:连接状态,LISTEM代表监听中
Recv-Q/Send-Q:接收/发送队列大小
Local Address:Port:本地监听的IP地址和端口

软件包管理

RockyLinux中使用npm命令和dnf命令来管理软件包,用于查看、下载、安装、卸载软件包等操作。

使用npm管理软件包

安装

1
sudo yum -y install nodejs npm

常用命令

命令 含有
npm -qa 查看所有已安装的软件包
npm -qa | more 分页查看
npm -qa | grep 包名 查看指定软件包
npm -q 包名 查看是否安装
npm -qi 包名 查看软件包信息
npm -ql 包名 查看属于软件包的所有文件
npm -qf 文件全路径 查看指定文件属于哪个软件包
npm -ivh 软件包全路径 安装软件包
npm -e 包名称(加–nodeps强制删除) 卸载软件包

使用dnf管理软件包

dnf会一次性安装软件包以及软件包所需要的依赖。

常用命令

命令 作用
dnf -y install 软件包名 安装
dnf remove 软件包名 卸载
dnf autoremove 卸载无用软件包名
dnf search 关键词 搜索软件包名
dnf list 列出所有可用软件包
dnf list installed 列出已安装的软件包
dnf updates 列出可更新的软件包
dnf info 软件包名 查看软件包信息
dnf update 更新所有可升级的软件包
dnf update 软件包名 更新指定软件包
dnf check-update 检查可更新的软件包
dnf clean all 清楚缓存
dnf makeche 重建缓存
dnf repolist 列出可用仓库
dnf repolist all 列出所有仓库

日志管理

在Linux下使用rsyslogd服务来管理日志文件,它是一个后台服务。

常用命令

1
2
3
4
5
#查看是否启动
ps -aux | grep rsyslog

#查看是否开机自启
systemctl -list-unit-files | grep rsyslog

编辑日志文件时的格式

1
2
3
4
5
#格式
*.*
#解释
第一个*:代表日志类型
第二个*:代表日志级别

类型解析

类型 含义
auth pam产生的日志
authpriv ssh、ftp等登陆信息的验证信息
corn 时间任务相关
kern 内核相关
lpr 打印相关
mail 邮件相关
mark(syslog)-rsyslog 服务内部信息
news 新闻组
user 用户程序产生的相关信息
uucp 主机之间相关的通信信息
local 1-7 自定义的日志设备

级别解析

注意:从上到下,级别从低到高,记录信息越来越少!!!

级别 含义
debug 调试、通信
info 一般信息,最常用
notice 具有重要性的普通条件
warrning 警告
err 错误
crit 严重
alert 需要立刻修改
emerg 内核崩溃
none 什么都不记录

怎么看日志文件

日志文件的格式包含以下4列

1、事件产生的时间

2、产生事件的服务器主机名

3、产生时间的服务名或程序名

4、事件的具体信息

自定义日志

通过编辑/etc/rsyslog.conf文件来完成;

修改后重启才能生效!!!

1
2
3
4
5
6
vim /etc/rsyslog.conf

#最后添加
类型.级别 /var/log/文件名.log
#例如ssh类型,任意级别
authpriv.* /var/log/testssh.log

日志轮替

日志轮替就是把旧的日志文件移动并改名,同时建立新的空日志文件,当旧日志文件超出保存的范围之后,就会进行删除。

使用logrotate进程日志轮替管理,/etc/logrotate.cong作为全局日志轮替规则配置文件 , 也可以给单独某个日志文件指定策略

当进行轮替时初始日志文件会改名成 原文件名1 , 然后会使用旧文件名新建一个空的日志文件 , 依次类推

全局规则配置文件参数解析

参数 含义
weekly 每周轮替一次
rotate 数字 按数字保存几份
create 创建新空的日志文件
dateeext 使用日期作为日志轮替文件的后缀

自定义日志加入日志轮替

所有自定义日志规则全部放在/etc/logrtate.d目录下,此目录下的所有文件都会被加载进全局规则配置文件中

日志轮替的参数说明

参数 含义
daily 每天一换
weejly 每周一换
monthly 每月一换
rotate 数字 按数字保存几份
compress 轮替时,旧的会被压缩
create mode owner group 新建日志文件,同时指定权限\所有者\所属组
mail address 轮替时,输出内容到指定邮件地址
missingok 日志不存在时忽略警告信息
notifempty 日志文件为空,不轮换
minsize 轮替最小值才会替换
size 指定大小,忽略时间限制
dateext 使用日期作为日志轮替文件的后缀
sharedscripts 在此关键字后执行一次脚本
prerotate/endscript 在轮替前或者后执行脚本

内存日志

内存日志一旦重启即可清空;

内存日志使用journalctl来操作;

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#查看全部
journalctl

#查看最新三条
journalctl -n 3

#查看时间段
journalctl --since 开始时间 --until 结束时间

#查看保存日志
journalctl -p err

#查看日志详细内容
journalctl -o verbose

#查看指定日志信息
journalctl | gerp 服务名

备份与恢复

实体机是无法做快照的,如果系统出现异常或数据损坏,后果很严重,这时需要备份和恢复。

在linux中使用dump命令来进行备份

安装

1
dnf -y instal dump

dump基本介绍

dump支持分卷和增量备份,增量备份的意思是指备份上次备份后所增加的文件或修改的文件,不会把备份过的再备份一次;

分区才支持增量备份,文件和目录不支持增量备份!!!

语法

1
dump [选项] [目录或文件] 

选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-c:创建新的归档文件,c是具体的数字层级0-9

-f:指定备份后文件名

-j:将备份好的文件压缩成bz2格式,让文件更小

-T:指定开始备份的时间与日期

-u:本完成后在/etc/dumpdares中记录备份的文件系统,层级,等信息。

-t:指定文件名

-W:显示需要备份的文件以及最后一次备份的层级,时间,日期

-w:与-W相似,只显示需要备份的文件

在linux中使用restoer来恢复已备份的文件

安装

1
dnf -y install restoer

语法格式

1
restore [模式选项] [选项]

模式选项,不能混用,一次命令只能用一种

1
2
3
4
5
6
7
-C:使用对比模式,已备份文件和未备份的文件对比

-i:交互模式进行恢复

-r:进行恢复模式

-t:查看模式

选项

1
-f:从指定的文件中读取备份数据,进行恢复操作

MySQL

什么是MySQL?

MySQL它是一个关系型数据库管理系统,Oracle旗下产品;是最流行的关系型数据库管理系统之一,将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,以此增加了速度并提高了灵活性;其次它使用SQL语言用于操作数据库的标准语言,以其体积小、速度快、成本低广受个人及企业的喜爱;

SQL语句分类

**DDL:**数据定义语言,用来定义数据库、表、列等

**DML:**数据操作语言,用来对数据库表中的数据进行增删改查

**DQL:**数据查询语言,用来查询数据库表中的数据

**DCL:**数据控制语言,用来定义数据库的访问权限和安全级别,以及创建用户

MySQL常用数据类型

数值

1
2
3
4
5
int:标准的整数,4个字节
bigint:较大整数数据,8个字节

float:浮点数,4个字节
double:浮点数,8个字节

字符串

1
2
3
char:固定字符串
varchar:可变字符串
text:文本

时间日期

1
2
3
date:年月日,YYYY-MM-DD
time:时分秒,HH:mm:ss
datetime:年月日时分秒,YYYY-MM-DD HH:mm:ss

安装

1、配置MySQL软件仓库,具体配置获取;清华大学软件源官网https://mirrors.tuna.tsinghua.edu.cn/help/mysql/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#创建mysql.repo
vim /etc/yum.repos.d/mysql.repo

#从清华大学软件源官网复制MySQL软件源配置,并填入,不要直接复制下面的!去官网复制
[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-connectors-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-tools-community]
name=MySQL Tools Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-tools-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-8.0-community]
name=MySQL 8.0 Community Server
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-8.0-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

2、清理缓存、更新数据源

1
2
3
dnf clean all

dnf makecache

3、安装、启动、开机自启MySQL

1
2
3
4
5
dnf -y install mysql-community-server

systemctl start mysqld

systemctl enable mysqld

4、修改密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#获取临时密码
grep 'temporary password' /var/log/mysqld.log

#使用临时密码登陆
mysql -uroot -p
输入临时密码

#修改密码,新密码要包含大写字母、小写字母、特殊符号,例如:Yang@963214
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';

ALTER USER 'root'@'localhost' IDENTIFIED BY 'Yang@963214';

#退出MySQL
exit

#测试使用新密码登入

5、运行安全配置,交互模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql_secure_installation

#输入密码
Enter current password for root (enter for none):新密码

#是否修改密码,按 n ,刚刚已经修改了
Set root password? [Y/n] n

#是否删除匿名用户,按 y 删除
Remove anonymous users? [Y/n] y

#是否禁止root用户远程登陆,按 y 禁止,如果是个人用的话可以不用禁止
Disallow root login remotely? [Y/n] y

#是否删除test数据库,按 y 删除
Remove test database and access to it? [Y/n] y

#是否重新加载权限表,按 y 重新加载
Reload privilege tables now? [Y/n] y

6、查看

1
2
3
4
5
6
7
8
9
10
11
#运行状态
systemctl status mysqld

#进程情况
ps -ef | grep mysql

#查看端口号
ss -tulnp | grep mysql

#连接情况
ss -a | grep mysql

7、新建用户提供远程登陆,root已被禁止远程登陆

1
2
3
4
5
6
7
8
#登入mysql,新建用户
CREATE USER 'viper'@'%' IDENTIFIED BY 'Yang@963214';

#赋予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'viper'@'%' WITH GRANT OPTION;

#刷新权限
FLUSH PRIVILEGES;

8、配置防火墙

1
2
3
4
5
6
7
8
#放行MySQL默认端口
firewall-cmd --permanent --add-port=3306/tcp

#重新加载防火墙
firewall-cmd --reload

#查看是否放行
firewall-cmd --permanent --query-port=3306/tcp

9、使用Navicat测试

1
2
用户名:viper
密码:Yang@963214

DDL

数据定义语言,用来定义数据库、表、列等操作;

操作数据库

1、创建数据库

1
2
#可选项 if not exists 如果数据库不存在才创建
create database [if not exists] 数据库名;

2、使用数据库

1
user 数据库名;

3、查看当前使用的数据

1
select database();

4、查看所有数据库

1
show database;

5、删除数据库

1
2
#可选项 if not exists 如果数据库存在才删除
drop database [if exists] 数据库名;

操作表

====== 创建表 ======

1
2
3
4
5
6
7
8
#可选项 if not exists 检查该表不存在才会创建
#注意:最后一行不用加 , 号,不然会报错
create table [if not exists] 表名(
字段名1 数据类型1,
字段名2 数据类型2,
...
字段名n 数据类型n
);

====== 查询表 ======

1
2
3
4
5
#查看当前数据库下所有表名称
show tables;

#查看指定表的结构
desc 表名;

====== 修改表 ======

1、修改表名

1
alter table 表名 rename to 新表名;

2、添加一列

1
alter table 表名 add 列名 数据类型;

3、修改数据类型

1
alter table 表名 modify 列名 新数据类型;

4、修改列名和数据类型

1
alter table 表名 change 新列名 新数据类型; 

5、删除列

1
alter table 表名 drop 列名;

====== 删除表 ======

1
2
#可选项 if not exists 检查表是否存在才会删除
drop [if not exists] 表名;

DML

数据操作语言,用来对数据库表中的数据进行增删改查;

添加数据

1
2
3
4
5
6
7
8
9
10
#给指定列添加数据
insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);

#给全部列添加数据
insert into 表名 values(值1,值2......);

#批量添加数据
insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n),values(值1,值2,...值n)....;

insert into 表名 values(值1,值2,...值n),values(值1,值2,...值n)....;

修改数据

1
2
#注意:不加添加条件则会删除所有数据!!!
update 表名 set 列名1=1,列名2=2... where 条件;

删除数据

1
2
#注意:不加where条件将删除所有数据
delete from 表名 where 条件;

DQL

数据查询语言,用来查询数据库表中的数据;

基础查询

1
2
3
4
5
6
7
8
9
10
11
#查询表中所有数据
select * from 表名;

#查询多个字段数据
select 字段列表 from 表名;

#去重
select distinct 字段列表 from 表名;

#取别名 asas可以省略不写
select 字段名 as 别名 from 表名;

条件查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
select 字段列表 from 表名 where 条件列表;

#条件符号
>:大于
<:小于
>=:大于等于
<=:小于等于
=:等于
!=:不等于
between...and...:在某个范围之内
in(...):多选一
is null:是null
is not null:不是null
and:并且
or:或者
not:非,不是

模糊查询

通配符:_代表任意单个字符,%代表任意多个字符

1
select 字段列表 from 表名 where 字段名 like '匹配项';

排序查询

排序方式:asc代表升序排序(默认),desc代表降序排序

1
select 字段列表 from 表名 order by 排序字段名 排序方式;

聚合函数

将一列数据作为一个整体,纵向计算,null值不参加所有聚合函数运算;

====== 分类 ======

函数名 功能
count(列名) 统计数量
max(列名) 最大值
min(列名) 最小值
sum(列名) 求和
avg(列名) 平均值

====== 聚合函数语法格式 ======

1
select 聚合函数名(列名) from 表;

分组查询

1
select 字段列表 from 表名 [where 分组前条件限定] group by 分组字段名 [having 分组后条件过滤];

where和having的区别

1、执行时机不同,where是分组前限定,不符合的不参与分组,having则是分组后对结果进行过滤,不符合的不会显示结果;

2、可判断的条件不一样,where条件不能对聚合函数进行判断,having可以。

分页查询

起始索引计算公式:当前页码-1 * 每页显示的条目

1
select 字段列表 from 表名 limit 起始索引 , 查询条目数;

DCL

数据控制语言,用来定义数据库的访问权限和安全级别,以及创建用户;

用户管理

创建用户

1
2
3
4
5
# %允许所有主机访问,localhost表示仅本地访问
create user '用户名'@'允许访问的主机' identified by '密码';

create user 'viper'@'%' identified by '000000';
FLUSH PRIVILEGES;

修改用户名

1
rename user '旧用户名'@'host' to '新用户名'@'host';

修改密码

1
alter user '用户名'@'host' identified by '新密码';

删除用户

1
drop user '用户名'@'host';

权限管理

常用权限

关键字 含义
select 允许查询数据
insert 允许插入数据
update 允许修改数据
delete 允许删除数据
create 允许创建库/表
alter 允许修改表结构
drop 允许删除库/表
index 允许创建/删除索引
execute 允许执行存储过程
all 所有权限

授于权限

1
2
3
4
grant 权限类型 on 数据库名.表名 to '用户名'@'host';

grant all on ry to 'viper'@'host';
FLUSH PRIVILEGES;

查看权限

1
2
show grant for '用户名'@'host';
show grant for 'viper'@'host';

撤销权限

1
2
revoke 权限类型 on 数据库名.表名 to '用户名'@'host';
FLUSH PRIVILEGES;

角色管理(8.0及以上版本才支持)

除了直接赋予用户权限外,还可以通过角色的形式赋予用户权限。

创建角色

1
create role '角色名称';

授于角色权限

1
grant 权限类型 on 数据库名.表名 to '角色名称';

将角色授予用户

1
grant '角色名称' to '用户名'@'host';

激活角色

1
set default role all to '用户名'@'host';

约束

约束作用于表中列上的规则,用于限制加入表的数据,保证了数据的正确性、有效性和完整性。

约束分类

名称 关键字 功能
非空约束 not null 保证列中所有数据不能有null值
唯一约束 unique 保证列中所有数据各不相同
主键约束 primary key 一行数据唯一标识符,要求非空且唯一
默认约束 default 保存数据时,未指定值则采用默认值
外键约束 foreign key 用来让两个表的数据之间建立连接,保证数据的一致性和完整性

外键约束

1、建表时添加

1
constraint 外键名称 foreign key(外键列名) references 主表名(主表列名);

2、建完表后添加

1
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表名称(主表列名);

3、删除外键

1
alter table 表名 drop foreign key 外键名称;

多表查询

多表查询分类

内连接:查询两表交集部分的数据

左外连接:查询左边表和交集所有的数据

右外连接:查询右边表和交集所有的数据

子查询:查询中嵌套查询

连接示意图

image-20250513115127934

内连接

语法格式

1
2
3
4
5
#隐式内连接
select 字段列表 from1 , 表2... where 条件;

#显式内连接,inner可以省略不写
select 字段列表 from1 inner join2 on 条件;

左外连接

语法格式

1
select 字段列表 from1 left join2 on 条件;

右外连接

1
select 字段列表 from1 right join2 on 条件;

子查询

语法格式

1
2
3
4
5
6
7
8
#单行单列,作为条件值
select 字段列表 from 表名 where 字段名 = (子查询);

#多行单列,作为条件值,使用in关键字进程判断
select 字段列表 from 表名 字段名 in (子查询);

#多行多列,作为虚拟表
select 字段列表 from (子查询) where 条件;

事务

事务是一种机制、一个操作序列,包含了一组数据库操作命令,事务会将这些操作命令作为一个整体一起向系统提交或撤销操作请求,这时这一组命令要们全部成功,要们全部失败。

语法格式

1
2
3
4
5
6
7
8
#开启事务
begin;

#提交事务
commit;

#回滚事务
rollback;

事务四大特征(ACID)

原子性:要们同时成功,要们同时失败

一致性:事务完成时,必须保证所有数据都保持一致

隔离性:多个事务之间相互隔离,当一个事务在操作时不应被另一个事务干扰

持久性:事务一旦提交或回滚,它的数据的修改就是永久的

事务的隔离级别

===== 读未提交 ======

特点:事务可以读取到其它事务未提交的数据

问题:会出现脏读,事务A读取了事务B未提交的修改,如果B回滚了事务,那么A事务读取到的数据就是无效的。

===== 读已提交 ======

特点:事务只能读取到其他事务已提交的数据

问题:会出现不可重复读,事务A两次读取同一数据,中间事务B修改并提交了事务A读取的数据,导致A事务两次读取到的数据不一致。

===== 可重复读======

特点:事务执行期间,多次读取同一数据结果一致,是MySQL默认隔离级别

问题:会出现幻读,事务A读取某个范围的数据,事务B插入了新数据并提交,事务A再次查询时发现凭空出现的数据。

===== 序列化======

特点:最高隔离级别,所有事务串行执行(类似单线程),完全避免并发问题

问题:性能极低,可能会导致大量锁等待或死锁

索引

什么是索引?

索引时数据库中用于快速查找数据的数据结构,类似书籍的目录,使用索引可以快速定位到需要查找的数据,减少数据库需要扫描的数据量。

索引分类

普通索引:最基本的索引,无特殊限制,关键字 inde/key

唯一索引:索引列值必须唯一,允许null值,关键字 unique key

主键索引:特殊的唯一索引,不允许null值,关键字 primary key

全文索引:用于全文搜索 FullText

创建索引

1
2
3
4
5
#创建表时
create 索引类型 索引名称 on 表名(列名);

#创建表后
alter table 表名 add 索引类型 索引名称(列名);

查看索引

1
show index from 表名;

删除索引

1
drop index 索引名称 on 表名;

索引使用场景

====== 适合作为索引的字段 ======

1、主键

2、频繁作为查询条件的字段

3、查询中排序的字段

4、查询中统计或分组的字段

====== 不合适作为索引的字段 ======

1、频繁更新的字段

2、数据量小的表

3、数据量重复且分布均与的字段

备份与导入

备份

1
mysqldump -h主机 -u用户名 -p 数据库 表 > 存储路径/备份文件名.sql

导入

1
2
#登陆后
source sql文件所在路径

Shell基础

什么是shell?

shell是用户和操作系统内核交互的接口,可以使用shell编写脚本来自动执行一系列命令和操作。


shell执行方式

分类

1、在当前shell环境运行

​ 1):./脚本

​ 2):soucre 脚本

2、开启子shell环境运行

​ 1):bash 脚本

​ 2):sh 脚本

两者区别

1、子shell会开启新线程,当前shell不会

2、当前shell修改变量是永久性的,子shell则仅子shell内有效

3、当前shell运行速度快,子shell因为要创建子线程运行比前者慢

shell快速入门

1
2
3
#!/bin/bash

echo 'hello-shell'

shell变量

什么是变量?

变量是内存中的一小块存储空间,存储自己指定的值,然后给这小块空间取个名字,当我们要用到值的时候通过变量的名字就能拿到对应的值。

shell变量分类

系统变量:系统本身定义好的,可以直接用

自定义变量:需要用户自己来定义

环境变量:应用运行时需要环境变量,我们不能每次都进入指定目录下运行,太过繁琐,只需要在/etc/profile下指定该应用的环境变量,这样在哪里都可以使用该应用了,例如JDK

预定义变量:获取命令行信息

shell变量的基本语法

1
2
3
4
5
6
7
8
9
10
#定义变量
变量名=值

#撤销变量
unset 变量名

#静态变量,值不可变,不能撤销
readonly 变量名=值

#``和$()可以将命令的返回值赋值给变量

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash

name='Tom'
age=1001

unset age

readonly sex='女'

time=`date`

data=$(date)

echo "$name-----------$age---------$sex-------------$time---------$data"

环境变量

1
2
3
4
5
6
7
8
9
10
vim /etc/profile

#定义
exprot 变量名=值

#修改立即生效
source /etc/profile

#查看
echo $变量名

位置变量

$0:代表命令本身

$1-9:代表一到九的参数

${9以上的数字}:代表十或十以上的参数

$*:代表所有参数,看作一个整体

$@:代表所有参数,分别看待每一个参数

$#:代表参数的总个数

$?:返回上一次命令执行结果,0成功,非0失败

$$:表示当前shell的PID

$!:上一个后台进程的PID

$_:获取上次命令最后一个参数

1
2
3
4
5
6
7
8
9
#!/bin/bash

echo "名字=======$1 || 年龄========$2"

echo "测试\$*========$*"

echo "测试\$@========$@"

echo "测试\$#=========$#"

shell运算式

shell中有三种运算格式

1
2
3
4
5
6
7
8
#第一种
$((运算式))

#第二种,推荐使用
$[运算式]

#第三种,它的乘号用 \*,想得到它的值需要用 `` 符号括起来
变量名=`expr 值1 运算符 值2`

shell流程控制

if语句

判断给出的运算式执行相应操作

if语句基本格式

1
2
3
4
if [ 条件判断式 ]
then
操作
fi

常用判断比较符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
比较字符串用:=

#整数类比较
-lt:小于
-le:小于等于
-eq:等于
-gt:大于
-ge:大于等于
-ne:不等于

#权限类判断
-r:是否可读
-w:是否可写
-x:是否可执行

#文件类型判断
-f:判断文件是否存在且是一个常规文件
-e:判断文件是否存在
-d:判断文件是否存在且是目录


#逻辑运算符
&&:并且,左右结果必须都为真
||:或者,左右任意一个结果为真即可
!:取反

练习

1
2
3
4
5
6
7
8
#!/bin/bash

number=100

if [ $number -lt 200 ]
then
echo "$number小于200"
fi

if多分支语法格式

1
2
3
4
5
6
if [ 运算判断式 ]
then
业务代码
elif [ 运算判断式 ]
业务代码
fi

练习

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

number=100

if [ $number -gt 200 ]
then
echo "$number大于200"
elif [ $number -gt 50 ]
then
echo "$number大于50"
fi

case语句

语法格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
case $变量 in
"值1")
业务代码1
;;
"值2")
业务代码2
;;
"值3")
业务代码3
;;
*)
默认业务代码
;;
esac

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

data=80

case $data in
"90")
echo "90分"
;;
"80")
echo "80分"
;;
*)
echo "没有对应分数"
;;
esac

for循环

第一种语法格式

1
2
3
4
5
#在列表值内都可循环
for 初始变量 in "值列表"
do
业务代码
done

第二种语法格式

1
2
3
4
for((初始变量;条件表达式;变量变化))
do
业务代码
done

第一种练习

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

sum=0

for i in {1..100}
do
sum=$[$sum+$i]
done

echo "1加到100等于======$sum"

第二种练习

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

sum=0

for ((k=0;k<=100;k++))
do
sum=$[$sum+$k]
done

echo $sum

while循环

语法格式

1
2
3
4
5
# [ ] 左右都有空格
while [ 条件表达式 ]
do
业务代码
done

练习

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

sum=0
j=0

while [ j<100 ]
do
sum=$[$sum+$j]
$j++;
done

echo $sum

键盘录入

在shell中使用read命令来获取用户输入的信息。

语法格式

1
2
3
4
5
read 选项 参数

#常用选项
-p:提示信息
-t:等待时间(秒)

练习

1
2
3
4
5
6
7
8
9
#!/bin/bash


read -t 10 -p '请输入用户名:' name

read -t 10 -p '请输入年龄:' age


echo "输入信息:用户===$name;年龄===$age"

数组

什么是数组?

数组是一种存储多个值的数据结构,可以按索引访问。

数组分类

普通数组:索引是数字,有序

关联数值:索引是单词,以key-value形式存储,类似Map形势,无序,索引不能重复,值可以

普通数组

1
2
3
4
5
6
7
8
9
10
11
#定义
数组名=(值1 值2 值3 ...)

#访问数组全部数据
${数组名[*]}

#根据指定索引访问对应数据
${数组名[索引]}

#获取数组长度
${#数组名[*]}

关联数组

1
2
3
4
5
6
7
8
#定义,先创建,再放值
declare -A 数组名
数组名=([索引1]=值1 [索引2]=值2 [索引3]=值3 ...)

#访问和普通数组一样
${数组名[索引]}
${数组名[*]}
${#数组名[*]}

循环操作数组

插入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#普通数组使用while循环插入数据
#!/bin/bash

#将/etc/profile里的内容循环写入数组中
while read line
do
arr[++i]=$line
done < /etc/profile

echo ${#arr[@]}

#遍历
for((k=0;k<${#arr[@]};k++))
do
echo ${arr[k]}
done





#关联数组使用while循环插入数据
#!/bin/bash

#将/etc/profile里的内容循环写入数组中

declare -A arr
i=0
while read line
do
arr["index_$i"]=$line
((i++))
done < /etc/profile

echo ${#arr[@]}

#遍历
for((k=0;k<${#arr[@]};k++))
do
echo "${arr["index_$k"]}"
done

函数

什么是函数?

在shell中函数是一组可以重复使用的命令集合,可以接收参数并返回状态或值。

语法格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#第一种
function 函数名 {
业务代码
}

#第二种,推荐使用
函数名() {
业务代码
}

#调用
函数名

#带参调用,定义了几个参数就写几个值
函数名 值 ...

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#不带参
showTest() {
ls /yzg/shell >> yzg.java
}

showTest

#带参
#!/bin/bash

sum=0

showTest() {
sum=$[$1+$2]
}

showTest $1 $2

#获取状态码
if [ $? -eq 0 ]
then
echo "执行成功!==========状态码:$?============相加结果:$sum"
fi

初级Linux运维面试题


系统基础

1、简述Linux启动流程?

1
2
3
4
5
6
7
8
9
1):首先是BOIS硬件自检,按照配置顺序查找可启动设备,读取磁盘第一个扇区或EFI分区中的引导程序;

2):其次是Boot Loader引导加载程序,加载所选内核镜像和初始化内存盘;将控制权交给内核;

3):接着是内核初始化,解压并加载内核,检测并初始化CPU、内存、等硬件设备,根据启动参数挂载根文件系统,启动第一个用户空间进程;

4):然后是系统初始化,以systemd作为init进程,按依赖关系并行启动系统服务,运行启动脚本;

5):最后显示登陆页面,用户输入用户名和密码进入系统后加载用户配置和环境。

2、Linux常见的发行版有哪些?各有什么特点?*

1
2
3
#常见发型版本
基于 Debian 的发行版 Ubuntu,特点:强大社区支持、友好的用户界面、丰富的软件仓库;
基于 RHEL 的发行版 RockyLinux,特点 :适合企业服务器环境、免费、完全兼容RHEL

3、简述Linux目录结构和常见目录的作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#目录结构
Linux采用FHS文件系统层次结构标准,以 / 作为整个文件系统的起点,包含所有目录以及文件

#常见目录及作用
etc:存放系统配置文件
dev:存放设备文件
bin:存放系统基本命令
sbin:存放需要root权限才能执行的系统管理命令
boot:存放内核、引导、启动相关文件
home:存放用户家目录
proc:存放虚拟文件系统
run:存放系统启动后的临时文件
mnt:临时挂载点
opt:存放第三方软件
var:存放日志文件
tmp:存放临时文件

4、如何查看系统信息?

1
2
3
4
5
6
7
8
9
10
11
#查看内核版本
uname -a

#查看发行版信息
cat /etc/os-release

#查看主机名
hostnamectl

#查看当前用户
whoami

常用命令

1、ls常用选项以及ls -l 参数简述

作用:查看

1
2
3
4
5
6
7
8
9
#常用选项
-l:以列表形式展示
-a:显示隐藏文件
-lh:以人类可读格式展示大小,KB\MB\GB
-lS:降序排序
-lt:时间排序

#ls -l 参数简述
从左往右依次是:文件类别、权限、属组属主、大小、时间、名称

2、cp命令常用选项

作用:拷贝

1
2
3
4
5
6
7
8
9
-r:递归拷贝
-p:保留原文件属性
-a:保留所有属性并递归复制
-i:覆盖前询问
-n:不覆盖已存在的文件
-b:覆盖前创建简单备份
-L:拷贝链接指向的源文件
-s:只拷贝链接
-v:显示过程

3、mv命令常用选项

作用:移动

1
2
3
4
5
-i:覆盖前询问
-n:不覆盖
-b:覆盖前创建简单备份
-v:显示过程
-f:强制

4、find命令常用选项

作用:查找

1
2
3
4
5
6
-type:按类型查找,f 代表文件、d 代表目录、l 代表链接
-size:按大小大小
-user:按属主查找
-a:与
-o:或
!:非

5、chmod命令

作用:设置权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#字母表示
r:可读
w:可写
x:可执行
u:属主
g:属组
o:其它组
a:所有组

#数字表示
6:可读
2:可写
1:可执行

#操作符
+:赋与权限
-:取消权限
=:精确权限

#常用选项
-R:递归修改目录及子目录权限
-v:显示修改后信息

6、chown命令

作用:修改文件或目录属组和属主

1
2
3
4
5
6
#语法格式
chown 选项 属组:属主 文件或目录

#常用选项
-R:递归处理
-v:显示详细处理信息

7、chrgp命令

作用:修改文件或目录属组

1
2
3
4
5
6
#语法格式
chgrp 选项 属组 文件或目录

#常用选项
-R:递归
-v:显示修改详细信息

8、chmod、chown、chgrp三个命令的区别

1
2
3
chmod是修改权限;
chown是修改属组和属主;
chgrp是修改属组

9、ps命令

作用:查看进程状态

1
2
3
4
#常用选项
-aux:查看所有进程详细信息
-ef:以完成格式查看进程列表
-u:查看指定用户进程

10、top命令

作用:实时查看进程信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#常用交互指令
q:退出
h:帮助
空格:立即刷新
1:显示所有CPU核心单独使用率
k:杀死进程
M:按内存占用排序
P:按CUP使用率排序
T:按运行时间排序
u:只显示某个用户的进程

#常用选项
-d:设置刷新时间
-p:只监控指定PID进程
-u:只显示指定用户进程

11、kill命令和killall命令

作用:终止进程

1
2
3
4
5
6
7
#常用选项
-9:强制终止
-15:默认终止,进程可以清理资源后退出

#区别
kill只会终止指定进程
killall会终止本进程和子进程

12、nice命令renice命令

作用:调整进程优先级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#优先级别
-20:最高优先级,仅root可设置
0:默认优先级
19:最低优先级

#启动新进程时设置优先级
nice -n 值 命令 #nice -n 1 touch yy.lop

#renice常用选项
-n:设置新nice值
-p:目标进程PID
-u:目标用户的所有进程

#查看优先级
top:PR参数
ps -l -p PID

## 三剑客

三剑客之grep

作用:根据条件查找匹配内容

1、如何查找包含”error”但不包含”warning”的日志行?

1
2
#使用 -v 选项取反
grep 'error' file | grep -v 'warning'

2、如何显示匹配行及其后3行内容?

1
2
#使用 -A , -B显示前行,-C显示上下行
grep -A 3 '关键字' file

3、如何统计文件中匹配模式的行数?

1
2
#使用-c
grep -c '关键字' file

4、如何递归搜索目录下所有文件中的关键字?

1
2
#使用-r递归
grep -r '关键字' /../../..

5、如何显示匹配行的行号?

1
2
#使用-n
grep -r '关键字' file

三剑客之sed

作用:用于删除、替换文本内容

1、如何替换文件中所有”foo”为”bar”?

1
2
#使用 s///g
sed 's/foo/bar/g' file

2、如何删除文件中的空行?

1
2
#使用^$
sed '/^$/d' file

3、如何只替换每行中第二次出现的匹配?

1
2
#使用s///2
sed 's///2' file

4、如何删除文件的第10行?

1
sed '10d' file	

5、如何显示文件的第5到第10行?

1
2
#使用-n加p指令
sed -n '5,10p' file

6、如何在第5行后添加一行

1
2
#使用a指令
sed '5a 添加的内容' file

7、如何在第5行前添加一行

1
2
#使用i指令
sed '5i 添加的内容' file

8、如果将第6行替换成================

1
2
#使用c指令
sed '6c ====================' file

三剑客之awk

作用:字段提取、统计

1、如何打印文件的第2列?

1
awk '{print $2}' file

2、如何统计文件的行数?

1
awk '{print }'

3、如何统计文件列数?

1
awk ‘{print NF}’ file

4、如何按IP统计访问日志中的访问次数?

1
awk '{ip[$1]++} END {for (i in ip) print ip[i],i}' file | sort -nr

5、如何打印文件中长度超过80个字符的行?

1
awk 'length($0) > 80' file

用户与用户组

1、/etc/passwd文件的字段含义是什么?

1
2
3
从左往右依次是=用户名:密码:UID:GID:描述信息:家目录:登录shell

#密码 x 表示密码在shadow文件中

2、/etc/shadow文件的字段含义?

1
从左往右依次是=加密密码:最后修改时间:最小天数:最大天数:警告天数:不活动天数:失效天数:保留字段

3、简述UID和GID的范围规则

1
2
3
0:表示root用户
1~999:表示系统用户
1000+:表示普通用户

4、如何创建新用户并指定家目录和登录shell?

1
2
3
4
5
6
useradd -m -p 家目录路径 -s /bin/bash

#解释
-m:如果家目录不存在自动创建
-p:指定家目录路径
-s:指定shell路径

5、如何修改用户密码

1
passwd 用户名

6、如何锁定和解锁用户

1
2
3
4
5
#锁定
passwd -l 用户名

#解锁
passwd -u 用户名

7、如何修改用户UID和主组?

1
usermod -u 新UID -g 新组

8、如何删除用户并同时删除家目录?

1
userdel -r 用户名

9、如何将用户添加到附加组?

1
usermod -aG 组名 用户名

10、怎么查看用户所属组

1
id 用户名

11、如何创建新用户组并指定GID?

1
groupadd -g GID 组名

12、如何删除用户组?

1
groupdel 组名

sudo

作用:授权A用户以B用户的身份执行操作

主配置文件:/etc/sudoers

附加配置文件:/etc/sudoers.d

常用配置项

1
2
3
4
5
6
7
8
#允许用户执行所有命令
用户名 ALL=(ALL) ALL

#允许组内成员执行所有命令
组名 ALL=(ALL) ALL

#允许用户指定指定目录下命令
用户名 ALL=(ALL) 目录路径

磁盘管理

1、简述常见文件系统类型及特点

1
2
3
4
5
6
7
#ext4优缺点
优点:Linux默认文件系统,稳定、日志保证数据一致性,向后兼容ext2、ext3
缺点:最大支持1EB文件系统、单个16TB文件,高并发环境不如xfs

#xfs优缺点
优:高性能、高并发、超大文件支持,单个文件8EB,8EB文件系统,在线扩展不支持缩小;
缺点:不适合小文件,不支持缩小,如果日志文件损坏恢复较慢

2、添加一块新硬盘后,如何使用fidsk命令操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#查看
fdisk -l

#进入分区交互模式
fdisk /dev/sd?

n:添加新分区
p/e:p主分区/e逻辑分区,二选一
分区号默认
起始位置默认
终止位置:想分多少就+跟上数字和单位即可
w:保存退出

#格式化文件系统
mkfs -t 文件系统类型 分区路径

#临时挂载
mount 分区路径 挂载目录路径

#查看挂载情况
df -h

#查看分区文件类型和UID
lsblk -f

#永久挂载
vim /etc/fstab

分区路径 挂载目录路径 文件系统类型 defaluts 0 0

3、添加一块新硬盘后,如何使用parted命令操作

1
2
3
4
5
6
7
8
9
10
11
12
13
#查看
parted -l

#分区
parted /dev/sdb
mklabel gpt:将磁盘格式化为gpt
mkpart primary 0GB 5GB:创建主分区,指定文件系统类型以及容量
print:查看创建结果

#格式化分区为指定文件系统
mkfs -t /dev/sdb1

#临时挂载、永久挂载和fdisk方式一样

4、操作raid磁盘阵列的常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#常用参数
-C:创建
-l:指定级别
-n:指定磁盘数量
-f:标记为故障盘
-a:添加磁盘
-r:移除

#创建
mdadm -C /dev/名称 -l 级别 -n 磁盘数量 所用的磁盘

#查看
mdadm -D 阵列名称

#挂载
mount /dev/名称 目录路径

#添加
mdadm /dev/名称 -a 要添加的磁盘

#卸载
umont /dev/名称

#停用
mdadm --stop /dev/名称

#删除
mdadm --zero-superblock 磁盘列表

5、简述LVM逻辑卷

LVM是Linux系统中用于灵活管理磁盘空间的一种技术,通过将物理磁盘抽象为逻辑卷,实现存储空间的动态调整。

PV:物理卷真实的物理磁盘或分区

VG:卷组,多个PV组成的资源池

LV:逻辑卷从VG中划分出来的逻辑磁盘,可以像普通磁盘一样挂载使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#创建PV物理卷
pvcreate 磁盘路径
#查看PV状态
pvdisplay


#创建VG资源池
vgcreate 名称 已初始化为pv卷磁盘路径(多个)
#查看VG资源池
vgdisplay vg资源池名称


#创建LV逻辑卷
lvcreate -L 大小 -n 逻辑卷名称 VG资源池名称
#查看LV逻辑卷
lvdisplay LV逻辑卷名称


#格式化逻辑卷
mfks -t 文件类型 /dev/VG名称/LV名称
#挂载
mount /dev/VG名称/LV名称 目标路径



# 扩容
#如果VG空间不足需要先将物理卷添加进资源池
vgextend VG名称 PV路径
#在原容量加
lvextend -L +大小 /dev/VG名称/LV名称
#直接设定成指定大小
lvextend -L 大小 /dev/VG名称/LV名称



# 缩减
#先缩减文件系统
umont /挂载点
e2fsck -f /dev/vg01/lv01
resize2fs /dev/VG名称/LV名称 大小
#再缩减LV逻辑卷
lvreduce -L 大小 /dev/VG名称/LV名称
#重新挂载
mount /挂载点



#缩减VG资源池
#先移动PV上的数据到其它PV
pvmove /dev/sd?
#VG移除PV
vgreduce VG名称 /dev/sd?
#删除PV
pvremove /dev/sd?

网络管理

1、OSI七层模型和TCP/IP四层模型的区别是什么?请详细说明每一层的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#OSI七层
物理层:负责比特流在物理介质上的传输,如网卡
数据链路层:提供节点到节点的可靠传输,如交换机
网络层:提供主机到主机的通信服务,如路由器
传输层:提供端口到端口的可靠数据传输,如TCP/UDP协议
会话层:负责建立、管理和终止会话,如RPC协议
表示层:负责数据格式加密和转换,如SSL协议
应用层:为应用程序提供网络服务接口。如HTTP协议

#TCP/IP
网络接口层:等同于 物理层+数据链路层,物理介质传输,MAC寻址
网络层:IP寻址、路由转发
传输层:提供端到端通信,如TCP
应用层:等同于 会话层+表示层+应用层,会话管理、提供各种网络应用服务

#不同点
OSI严格七层,TCP/IP将会话层、表示层、并入了应用层,将物理层和数据链路层并入了网络接口层
OSI是理论模型,强调通用性,TCP/IP是实用模型,源于实际协议
OSI由标准化组织制定,TCP/IP通过实践发展而来

2、TCP的三次握手和四次挥手

1
2
3
4
5
6
7
8
9
10
#三次握手建立链接
第一次握手:客户端发送一个SYN请求报文,并附带初始化序列号,表示希望请求建立链接,进入请求等待状态
第二次握手:服务器收到请求后,回复一个SYN同步和ACK确认报文,ACK字段确认客户端的序列号,同时生成服务器自己的序列号,进入同步收到状态;
第三次握手:客户都安收到服务器的确认后,再发一个ACK确认报文,确认服务区的响应,进入建立连接状态,连接完成。

#四次挥手
第一次挥手:客户端发送一个带有FIN标志的报文,表示客户端不再发送数据,但还可以接收数据,进入结束等待_1状态
第二次挥手:服务器收到客户端FIN报文后,发送一个ACK报文确认,确认序列号为收到的序列号加1,进入关闭等待状态,客户端收到ACK后进入结束等待_2状态
第三次挥手:服务器完成数据发送后,向客户端发送一个FIN报文,表示服务器不再发送数据,进入最后_确认状态
第四次挥手:客户端收到FIN报文后,发送ACK报文确认,服务器收到ACK后立即进入关闭状态

3、TCP和UDP协议的主要区别是什么?各自适用于什么场景?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#TCP
可靠性机制,例如数据校验
流量控制,例如动态调整发送速率
拥塞控制,例如慢启动、快速恢复
#应用场景
文件传输、网页浏览、电子邮件、数据库访问

#UCP
无需建立连接即可发送数据
固定8字节头部
无确认、无顺序控制、无流量控制
#应用场景
游戏通信、DNS查询、DHCP、物联网通信


4、如何在Linux系统中查看网络接口信息?如何启用/禁用某个网络接口?

1
2
3
4
5
6
7
8
9
10
11
12
13
#查看
ip addr

#ip命令禁用和启用
ip link set 网卡名称 down
ip link set 网卡名称 up

#使用nmcli命令禁用和启用
nmcil c down 网卡名称
nmcil c uo 网卡名称

#永久性操作
进入对应网卡配置文件修改 ONBOOT=yes/no

5、如何永久修改Linux系统的IP地址、子网掩码和默认网关?

1
2
3
4
#进入对应配置文件修改 /etc/NetworkManager/system-connections/
address=IP/子网位数
gateway=网关
dns=dns地址

6、Linux系统中/etc/hosts和/etc/resolv.conf文件的作用是什么?

1
2
3
4
5
#/etc/hosts
作用:本地主机名和IP地址映射表

#/etc/resolv.conf
作用:配置DNS解析,指定系统使用的DNS服务器和搜索域

7‘、简述ping命令的作用及使用

1
2
3
4
5
6
7
8
9
10
11
#作用
网络诊断、测试主机之间的网络连通性

#语法
ping 选项 目标主机

#常用选项
-c:指定此时
-i:指定发送间隔,秒
-s:指定大小,字节
-W:指定等待回复超时时间

8、简述traceroute命令的作用及使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#作用
网络诊断
#原理
发送一系列UDP数据包,利用IP协议的TTL字段实现

#语法
traceroute 选项 目标主机

#常用选项
-n:不解析IP为域名
-I:使用ICMP请求,类似ping
-T:使用TCP
-U:使用UDP
-p:指定目标端口
-f:指定起始跳数
-m:指定最大 跳数
-q:指定数据包数量
-w:指定超市时间

9、简述tcpdump的作用及使用

1
2
3
4
5
6
7
8
9
10
11
12
13
#作用
命令行抓包工具

#语法
tcpdump 选项 网卡名称

#常用选项
-i:指定网卡名称
-D:查看可用接口
-w:结果保存为 .pcap 文件
-r:读取.pcap文件



10、怎么通过SSH禁止root远程登陆

1
2
3
4
5
6
7
8
9
10
11
#进入sshd配置文件修改
vim /etc/ssh/sshd_config

#修改
PermitRootLogin no

#限制登陆用户,设置白名单
AllowUsers 用户名

# 禁用密码登录,仅允许密钥登录(更安全)
PasswordAuthentication no

11、密钥认证配置流程

1
2
3
4
5
#生成密钥
ssh-keygen -t rsa -b 4096 -C "注释"

#上传至服务器
ssh-copy-id -i ~/.ssh/id_rsa.pub 用户名@ip

包管理器

1、搜索软件包

1
dnf search 软件包名

2、安装软件包

1
dnf -y install 软件包名

3、更新所有软件包

1
dnf -y upgrade

4、更新指定软件包

1
dnf -y upgrade 软件包名

5、删除软件包

1
dnf -y remove 软件包名

6、列出已安装的软件包

1
dnf list installed

7、查看软件包信息

1
dnf info 软件包名

8、自动删除无用依赖

1
dnf autoremove

9、列出所有可用软件包

1
dnf list

10、列出所有启用的软件仓库

1
dnf repolist

服务管理

1、简述systemd的作用及使用

作用:初始化系统和管理服务,智能处理服务之间的依赖

注意点:journalctl日志存在内存中,重启、关机即失效!!!

启动服务

1
systemctl start 服务名称

查看服务状态

1
systemctl status 服务名称

停止服务

1
systemctl stop 服务名称

重启服务

1
systemctl restart 服务名称

设置开机自启

1
systemctl enable 服务名称

禁止开机自启

1
systemct disable 服务名称

重新加载服务

1
systemctl reload 服务名称

查看是否开机自启

1
systemctl is-enabled 服务名称

2、简述journalctl的作用及使用

作用:systemd下的日志管理工具,用于查看和分析系统以及服务的日志。

查看全部日志

1
journalctl

查看最新日志

1
journalctl -e

查看内核日志

1
journalctl -k

查看指定服务名日志

1
journalctl -u 服务名称

查看最新20条日志

1
journalctl -n 20

实时追踪日志

1
journalctl -f

按优先级筛选

1
2
3
#0-7,0最简单,7最详细
#3代表 err 普通错误,4代表 warning 警告,6代表 info 服务成功、操作记录的信息
journalctl -p 等级

3、如何配置日志切割

使用logrotate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#需要配置某个服务的日志切割时,在logrotate指定目录下创建定制规则即可
cd /etc/logrotate.d/

#常用参数
daily:每天切割一次
weekly:每周切割一次
monthly:每月切割一次
rotate <数字>:指定保留几份历史日志
compress:启用日志压缩,gzip格式
delaycompress:延迟压缩,下一次切割时在压缩
missingok:如果日志文件丢失则不报错
notifempty:如果日志文件为空,则不切割
postrotate....endscript:在日志切割后执行的命令或脚本
dateext:使用日志为后缀

#检查
logrotate -d /etc/logrotate.d/文件名

#强制切割
logrotate -f /etc/logrotate.d/文件名

Shell脚本

1、解释 #!/bin/bash 的作用

1
用于指定该脚本的解释器路径,当该脚本被执行会根据指定的解释器来解析和运行脚本

2、如何在 Shell 中定义和使用变量?

1
2
3
4
5
6
7
8
#定义
变量名=值

#使用
$变量名

#撤销
unset 变量名

3、简述shell的位置变量

1
2
3
4
5
6
7
8
$0:代表名称本身
$1-9:代表1-9的参数,9以上需要 {} 包裹
$@:代表所有参数,分别看待每一个参数
$*:代表所有参数,看作一个整体
$#:代表参数总个数
$?:返回上次的执行结果,0成功,非0失败
$$:代表当前shell的进程号
$_:获取上次命令的最后一个参数

4、编写一个脚本,计算 1 到 100 的整数和

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

sum=0

for(( k=0;k<=100 ))
do
sum=$[$sum+k]
done

echo $sum

5、如何检查一个文件是否存在?

1
2
3
4
5
6
#!/bin/bash

if [ -f /文件路径 ]
then
echo '存在'
fi

6、shell如何从文件中逐行读取内容?

1
2
3
4
5
while IFS= read -r line;do
echo $line
done < /文件路径

#IFS=:防止行首 / 行尾的空格被删除

7、简述shell判断和循环的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#if判断,结果满足条件才会执行
if [ 条件表达式 ]
then
fi

#数值常用比较符,字符串用 =
-lt:小于
-le:小于等于
-eq:等于
-gt:大于
-ge:大于等于
-ne:不等于

#循环,满足条件就会一直执行
while [ 条件表达式 ]
do
done

for 初始变量 in 参数列表
do
done

for (( 初始变量;条件;自增 ))
do
done

8、简述shell数组的作用以及使用

作用:存储多个值的数据结构,按索引来访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#定义数组
数组名=(值1,值2,...)

#访问数组全部数据
${数组名[@]}

#访问指定索引数据
${数组名[索引]}

#for循环遍历数组
for ((i=0;i<${数组名[@]});i++)
do
echo ${数组名[i]}
done

9、shell怎么获取用户输入的内容

1
read -t 等待时间 -p '提示内容' 变量

10、如何编写一个函数,并传递参数?

1
2
3
4
5
6
7
#!/bin/bash
sum=0
函数名(){
sum=$[$1+$2]
}

函数名 参数1 参数2

11、如何调试 Shell 脚本?

1
2
3
4
5
6
#第一种方式
bash -x 脚本文件

#第二种在脚本文件中指定开始和结束位置
开始位置:set -x
结束位置:set +x

安全基础

1、简述firewalld防火墙的使用

作用:管理防火墙

原理:将流量绑定到zone上,如网段流量、网卡流量,在zone内设定规则,不同流量访问不同的zone,在指定zone内没有匹配到就去默认zone内匹配。

启动、查看、停止

1
2
3
4
5
6
7
8
9
10
11
systemctl start friewalld 

systemctl status friewalld

systemctl stop friewalld

systemctl restart friewalld

systemctl enable friewalld

systemctl disable friewalld

操作zone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#查看默认zone
firewall-cmd --get-default-zone

#设置默认zone
firewall-cmd --set-default-zone=zone名称

#将网段关联到zone
firewall-cmd --permanent --add-source=IP网段/子网位数 --zone=zone名称

#将网段切换到其它zone
firewall-cmd --permanent --change-source=IP网段/子网位数 --zone=zone名称

#查看指定zone信息
firewall-cmd --list-all --zone=zone名称

#将网段移除zone内
firewall-cmd --permanent --remove-source=IP网段/子网位数 --zone=zone名称

#将网卡关联到zone
firewall-cmd --permanent --add-interface=网卡名称 --zone=zone名称

#删除、修改等操作和网段大同小异,关键字不同,source/interface

操作zone内规则

1
2
3
4
5
6
7
#以端口/协议方式
firewall-cmd --permanent --add-port=端口/协议 --zone=zone名称
firewall-cmd --permanent --remove-port=端口/协议 --zone=zone名称

#以服务形式
firewall-cmd --permanent --add-service=服务名称 --zone=zone名称
firewall-cmd --permanent --remove-service=服务名称 --zone=zone名称

性能监控

1、怎么查看CUP使用情况

1
2
3
4
5
6
7
8
9
10
#使用top命令
top

#常用指令
u:输入用户名后只显示该用户的进程
k:终止进程
M:按内存使用率排序
P:按CPU使用率排序
T:按使用CPU时长排序
1:显示每个CPU核心的使用情况

2、怎么查看内存使用情况

1
2
3
4
5
6
#使用free命令
free -h

#常用选项
-h:以人类可读展示
-s:指定多少秒刷新一次

3、怎么查看磁盘使用情况

1
2
3
4
5
6
#使用df命令
df -h

#常用选项
-h:以人类可读展示
-T:显示文件类型

4、简述vmstat命令的作用和使用

作用:监控系统资源

1
2
3
4
5
6
7
8
#语法格式
vmstat 选项 间隔时间 刷新次数

#常用选项
-s:显示内存统计摘要
-d:显示磁盘统计信息
-p:显示分区统计信息
-t:显示时间戳

故障排查

1、系统运行很慢处理流程

1
2
3
4
5
#第一步:使用top命令查看是不是某个进程使用CPU过载
#第二步:使用free命令查看内存情况,是否某个进程使用内存过载
#第三步:使用instat工具查看磁盘读写速率,iotop查看实时进程I/O占用
#第四步:使用网络宽带工具查看流量统计
#第五步:查看服务,是否由僵死进程,某个服务因为资源不足频繁重启或异常

2、磁盘空间不足的处理流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#第一步:先查看整体磁盘使用情况,看哪些分区使用率是否超过了%80甚至90
df -h

#第二步:使用ncdu工具定位大文件,根据第一步的结果进入该分区内查找大文件
ncdu [目录名称]
#常用指令
↑/↓:上下选择
回车键:进入选定目录
←:返回上级目录
d:删除所选文件或目录
s:按大小排序
t:按修改时间排序
q:退出

#第三步:清理日志和缓存临时文件
清理日志时:保留在写日志和最新备份
清理缓存临时文件时:需要确认无程序在使用

#如果不行就添加物理磁盘

4、服务无法启动的排查步骤

1
2
3
4
#使用systemd查看服务专题
#使用journactl日志工具查看分析报错信息
#检查服务配置文件是否有语法错误
#检查是否有端口冲突

5、忘记root密码处理流程

1、在开机动画页面按e

2、找到以linux16开头的段落,在末尾的UTF-8后面加上init=/bin/sh,再按ctrl+x键进入单用户模式

3、进入单用户名模式后输入,mount -o remount,rw / 回车

4、再次输入passwd后回车,输入第一次新密码后回车,再次输入新密码确定

5、再次输入touch /.autorelabel回车

6、最后输入exec /sbin/init回车,系统重启输入新密码即可


Ansible

1、什么是 Ansible?

1
它是有py开发的一款自动化运维工具,基于SSH协议一台管理节点控制多台子节点,实现任务分发到各子节点执行,此外还支持YAML格式编写playbook剧本。

2、简述 Ansible 的架构和工作原理

1
2
3
4
5
6
7
8
9
10
11
12
#架构
采用客户端的C/S架构,其核心组件:
Inventory:主机清单文件,定义管理的目标节点和主机
PlayBook:YAML格式的任务剧本
Module:执行具体任务的模块
Role:角色,可复用任务合集
Ad-Hoc:以命令形式将任务分发到子节点

#工作原理
阶段一:任务编排,解析PlayBook,根据Inventory主机清单筛选目标主机
阶段二:任务执行,将每个任务转换为py脚本,并通过SSH协议送到目标主机
阶段三:目标子节点将执行结果响应给管理节点

3、如何创建一个自定义的 Ansible Inventory 文件?动态 Inventory 是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#定义格式
#以IP定义
IP

#主机别名和IP
xxxx=IP

#定义组
[xxx]
IP

#定义子组
[xxxx:children]
组名
...

#为组定义全局变量
[组名:vars]
变量名=值
...


#使用时需要加 -i 参数指定

#动态Inventroy
动态从外部系统获取,如云平台,灵活实用

**4、编写一个简单的 Playbook 来在多个服务器上安装和启动 Nginx 服务。**
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#创建 files/index.html文件
Hello PitViper

#编辑templates模板
events {
worker_connections {{ number }};
}

#编辑vars变量
---
number: 1050
...

#编辑tasks任务
---
- name: install nginx
dnf: name=nginx state=present
- name: copy index.html
copy: src=index.html dest=/usr/share/nginx/html/index.html
- name: template nginx.conf.j2
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
- name: start nginx
systemd: name=nginx state=started

...

#编辑handlers触发
---
- name: restart nginx
systemd: name=nginx state=restarted
...

#site.yaml剧本
---
- hosts: viper
roles:
- nginx
...

#测试运行
ansible-playbook -i /root/inventory.ini site.yaml -C

5、如何在 Ansible Playbook 中使用条件语句?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#使用registe来定义变量,使用when判断结果,0表示已运行
name: shell test
shell: |
ll /hemo
register: yy

name: shell 22
shell
ll /opt
when: yy.rc == 0

#使用loop来定义循环,item代表循环里的元素
vars:
userlist: ['Tom','Cat']
tasks:
user:
name: "{item}"
state: present
loop: "{{ userlist }}"


6、Ansible常用模块有哪些?

1
2
3
4
5
6
7
8
9
10
copy模块
shell模块
user模块
gruop模块
systemd模块
file模块
script模块
软件包模块
cron定时模块
template模块

7、简述Tags属性

作用:指定运行哪些任务,没被Tags属性标记的则不会运行。

特殊标签:always:总是运行 / never:从不运行

1
2
3
4
5
6
7
8
9
#使用时
tags: 标签名称

#tags作用域
可以标记整个play
可以标记多个任务,标签名称相同就行
可以标记单个任务

使用 --tage 选项跟上 "标签名称" 即可运行指定标签任务

8、简述Handlers属性

作用:Handlers是一种特殊任务,它只会在playbook中指定任务发生了变化才会执行,如重启操作

1
2
3
4
5
6
7
#使用notify定义触发装置
notify:自定义名称

#触发后使用handlers来执行对应操作
handlers:
- name: notify定义的名称
操作

9、简述Role角色

作用:模块化、复用和组织任务,将playbook拆分称可复用组件

1
2
3
4
5
6
7
8
9
10
11
12
13
#目录结构
├── role_name
│ ├── file
│ │ └── index.html
│ ├── handlers
│ │ └── main.yaml
│ ├── tasks
│ │ └── main.yaml
│ ├── templates
│ │ └── xxx.j2
│ └── vars
│ └── main.yaml
└── site.yaml

10、简述ansible中的templates模板

作用:动态生成配置文件,让配置文件里的参数不再是写死一个数据,而是灵活替换,以模板文件以.j2为后缀


Docker

1、什么是Docker,Docker容器和虚拟机的区别

1
2
3
4
5
6
7
8
#什么是Docker
Docker是由Go语言开发的一款开源、容器管理平台,核心作用为将项目和项目所有依赖全部打包成镜像,解决在自己电脑上能运行,在其他电脑不行的问题

#区别
隔离角度:Docker是进程级,虚拟机是硬件级
启动速度:Docker是秒级,虚拟机是分钟级
资源占用:Docker直接使用宿主机内核,虚拟机需要完成OS内核
镜像大小:Docker是M级,虚拟是G级

2、Docker 的核心组件有哪些?

1
2
3
4
5
DockerD:后台服务,管理容器生命周期
Docker Cilent:Docker命令行交互工具
Docker Images:Docker镜像,用来创建容器
Docker 容器:正在运行中的镜像
Docker 镜像仓库:存放镜像

3、Docker 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#镜像命令
docker images #查看所有镜像
docekr inspect 镜像id或名称 #查看镜像元数据
docker search 镜像名称 #搜索镜像
docker pull 镜像名称:版本号 #拉取镜像,不加版本号默认最新
docker rmi 镜像ID或名称 #删除镜像
docker rmi $(docker images -aq)

#容器命令
docker run 选项 镜像id或名称 #启动镜像
#常用选项[--name:指定容器名称][-d:后台运行][-it:交互模式运行,exit:停止并退出容器,Ctrl+p+q:不停止容器退出容器][-p:指定真机和容器端口][-P:随机指定端口]

docker ps #查看容器,加-a查看所有容器
docker rm 容器id或名称 #删除容器,需要先停止容器
docker rm $(docker ps -aq) #删全部停止的容器
docker start 容器id或名称 #启动容器
docker restart 容器id或名称 #重启容器
docker stop 容器id或名称 #停止容器
docker kill 容器id或名称 #强行停止
docker logs 容器id #查看容器日志,加-f实时追踪容器日志

5、如何进入一个正在运行的容器?

1
docker exec -it 容器id或名称 /bin/bash

7、什么是Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
DockerFile是构建镜像的文本文件,包含了一些列指令,Docker引擎会根据DockerFile里的指令分层次构建镜像
#常用指令
FROM:指定基础镜像
RUN:执行命令,想让它干点啥
COPY:复制本地文件到镜像
ADD:类似COPY,额外支持解压和URL下载
WORKDIR:指定工作目录,进入容器后所在的目录
ENV:设置环境变量
EXPOSE:指定容器运行时监听的端口
USER:指定运行容器的用户
VOLUME:指定数据卷挂载点
CMD:容器启动时执行的命令
ENTRYPOINT:类似CMD

#COPY和ADD的区别
COPY:仅把文件复制到镜像
ADD:在COPY的基础上额外支持解压、URL下载

#CMD和ENTRYPOINT的区别
CMD:定义的命令,会被docker run所覆盖
ENTRYPOINT:不会被覆盖,而追加执行

#构建命令
docker build -f dockerfile文件 -t 自定义名称:版本 .

#查看构建过程
docker history 镜像名称:版本

8、Docker 有哪些网络模式?

1
2
3
bridge:桥接,利用docker0作为桥实现通信
host:容器直接使用宿主机网络,无隔离,高性能
none:无网络,仅lo回环接口

Docker网络常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#创建
docker network create --subnet 网段/子网位数 --gateway 网关 网络名称

#使用
在docker run启动容器的时间加上 --net 网络名称 即可将容器添加进网络

#查看所有网络
docker network ls

#查看网络详细
docker network inspect 网络名称

#将容器附加到其它网络,实现不同网络容器之间的通信,一个容器多个IP
docker network connect 网络名称 容器名称

#端口容器与网络的连接
docker network disconnect 网络名称 容器名称

#删除
docekr network rm 网络名称

10、Docker 的数据持久化方式有哪些?

1
2
3
4
5
6
第一种:直接使用 -v 挂载到宿主机
-v 宿主机路径:容器路径

第二种:使用数据卷
docker volume create 数据卷名称
docker run -v 数据卷名称:/容器名称/路径

11、如何以非 root 用户运行容器?

1
2
3
4
5
6
7
#第一种,在dockerfile中创建并指定用户
RUN useradd -m appuser && \
chown -R appuser:appuser /app
USER appuser

#第二种
在docker run时使用--user指定用户id和组id

12、如何限制容器的使用资源?

1
2
3
4
5
6
7
8
9
#限制内存
docker run时加上 --memory="数值?"指定内存资源,?表示单位单位m、g
--memory-swap="数值?" #显示内存和交换分区

#以权重限制CPU,默认1024
--cpu-shares=数值

#以核心限制CPU
--cpus="数值"

DockerCompose

1、什么是DockerCompse,用来解决什么问题?

1
2
DockerCompose是用来定义和运行多个Docker容器的工具,通过docker-compose.yaml文件配置服务、网络、存储等操作;
解决了繁琐使用docker run命令,简化多容器的管理,实现一键启动、停止、重建整个应用。

2、docker-compose.ymlDockerfile 的区别?

1
docker-compose.yaml定义的是多个容器的编排,DockerFile定义的是单个容器的构建步骤;

3、Docker Compose 的核心命令有哪些?

1
2
3
4
5
6
7
8
9
10
11
12
#启动
docker compose up
#停止并删除
docker compose down
#查看运行中的容器
docker compose ps
#查看日志
docker compose logs -f
#重构镜像
docker compose build
#进入容器
docker compose exec

4、DockerCompose的顶级元素有哪些

1
2
3
4
5
6
version:compose文件版本,v2版本可以不写
name:定义应用名称
volumes:定义数据卷
networks:定义网络
services:定义服务集合
environment:定义全局变量

5、如何设置容器启动顺序?

1
使用depends_on指定哪些服务在本服务之前启动

6、如何管理环境变量?

1
2
3
4
5
6
将变量统一放在一个隐藏文件内,使用env_file指定文件路径,compose会根据路径去读取变量;
也可以使用${}形式管理变量,在.env文件里定义使用${变量名}获取
定义:PASSWORD=000000
获取:
environment:
PASSWORD: ${PASSWORD}

7、如何调试 Docker Compose 启动失败的问题?

1
2
3
4
5
6
7
#第一步查看日志
docker compose logs 服务名称
#第二步进入容器检查
docker compose exec 服务名称 /bin/bash
#第三步检查依赖程序是否就绪,如数据库链接
#第四步验证配置文件语法
doucker compose config

8、docker compose up命令和docker compose start命令有啥区别

1
2
up:会创建新的容器
start:是启动已有容器

9、如何更新运行中的服务配置?

1
2
#使用-d参数,compose会智能更新
docker compose up -d

10、如何限制容器的 CPU/内存?

1
2
3
4
5
#使用resources配置项指定资源
resources:
limits:
cpus: "数值" #几核
memory: 数值和单位 #M/G
0%