一台 Linux 服务器最多能支撑多少个 TCP 连接?

一台 Linux 服务器最多能支撑多少个 TCP 连接?一台Linux机器上最多能建立多少个TCP连接?

困惑很多人的并发问题

我发现有很多同学对一个基础问题始终是没有彻底搞明白。那就是一台服务器最大究竟能支持多少个网络连接?我想我有必要单独发一篇文章来好好说一下这个问题。

很多同学看到这个问题的第一反应是65535。原因是:“听说端口号最多有65535个,那长连接就最多保持65535个了”。是这样的吗?还有的人说:“应该受TCP连接里四元组的空间大小限制,算起来是200多万亿个!”
如果你对这个问题也是理解的不够彻底,那么今天讲个故事讲给你听!

一次关于服务器端并发的聊天

"TCP连接四元组是源IP地址、源端口、目的IP地址和目的端口。任意一个元素发生了改变,那么就代表的是一条完全不同的连接了。拿我的Nginx举例,它的端口是固定使用80。另外我的IP也是固定的,这样目的IP地址、目的端口都是固定的。剩下源IP地址、源端口是可变的。所以理论上我的Nginx上最多可以建立2的32次方(ip数)×2的16次方(port数)个连接。这是两百多万亿的一个大数字!!"

"进程每打开一个文件(linux下一切皆文件,包括socket),都会消耗一定的内存资源。如果有不怀好心的人启动一个进程来无限的创建和打开新的文件,会让服务器崩溃。所以linux系统出于安全角度的考虑,在多个位置都限制了可打开的文件描述符的数量,包括系统级、用户级、进程级。这三个限制的含义和修改方式如下:"

  • 系统级:当前系统可打开的最大数量,通过fs.file-max参数可修改
  • 用户级:指定用户可打开的最大数量,修改/etc/security/limits.conf
  • 进程级:单个进程可打开的最大数量,通过fs.nr_open参数可修改

"我的接收缓存区大小是可以配置的,通过sysctl命令就可以查看。"

sysctl -a | grep rmem
net.ipv4.tcp_rmem = 4096 87380 8388608
net.core.rmem_default = 212992
net.core.rmem_max = 8388608

"其中在tcp_rmem"中的第一个值是为你们的TCP连接所需分配的最少字节数。该值默认是4K,最大的话8MB之多。也就是说你们有数据发送的时候我需要至少为对应的socket再分配4K内存,甚至可能更大。"

"TCP分配发送缓存区的大小受参数net.ipv4.tcp_wmem配置影响。"

sysctl -a | grep wmem
net.ipv4.tcp_wmem = 4096 65536 8388608
net.core.wmem_default = 212992
net.core.wmem_max = 8388608

"在net.ipv4.tcp_wmem"中的第一个值是发送缓存区的最小值,默认也是4K。当然了如果数据很大的话,该缓存区实际分配的也会比默认值大。"

服务端百万连接达成记

“准备啥呢,还记得前面说过Linux对最大文件对象数量有限制,所以要想完成这个实验,得在用户级、系统级、进程级等位置把这个上限加大。我们实验目的是100W,这里都设置成110W,这个很重要!因为得保证做实验的时候其它基础命令例如ps,vi等是可用的。“

活动连接数量确实达到了100W:

ss -n | grep ESTAB | wc -l  
1000024

当前机器内存总共是3.9GB,其中内核Slab占用了3.2GB之多。MemFree和Buffers加起来也只剩下100多MB了:

cat /proc/meminfo
MemTotal:        3922956 kB
MemFree:           96652 kB
MemAvailable:       6448 kB
Buffers:           44396 kB
......
Slab:          3241244KB kB

通过slabtop命令可以查看到densty、flip、sock_inode_cache、TCP四个内核对象都分别有100W个:

结语

互联网后端的业务特点之一就是高并发. 但是一台服务器最大究竟能支持多少个TCP连接,这个问题似乎却又在困惑着很多同学。希望今天过后,你能够将这个问题踩在脚下摩擦!

转载于 https://mp.weixin.qq.com/s/Lkyj42NtvqEj63DoCY5btQ

CentOS 7.8使用devtoolset-9使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)编译安装Redis 6.0.5

CentOS 7.8 编译安装Redis 6.0.5报错
In file included from server.c:30:0:
server.h:1045:5: error: expected specifier-qualifier-list before ‘_Atomic’
_Atomic unsigned int lruclock; /* Clock for LRU eviction */
^
server.c: In function ‘serverLogRaw’:
server.c:1028:31: error: ‘struct redisServer’ has no member named ‘logfile’
int log_to_stdout = server.logfile[0] == '\0';
^
server.c:1031:23: error: ‘struct redisServer’ has no member named ‘verbosity’
if (level < server.verbosity) return;
^
server.c:1033:47: error: ‘struct redisServer’ has no member named ‘logfile’
fp = log_to_stdout ? stdout : fopen(server.logfile,"a");
^
server.c:1046:47: error: ‘struct redisServer’ has no member named ‘timezone’
nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active);
^
server.c:1046:63: error: ‘struct redisServer’ has no member named ‘daylight_active’
nolocks_localtime(&tm,tv.tv_sec,server.timezone,server.daylight_active);
......
......

问题原因
CentOS 7的gcc版本为4.8.5,Redis 6.0.5最低需要gcc4.9,因此需要升级gcc版本
from redis 6.0.5, building redis from source code needs C11 support.The version of gcc in CentOS 7 is 4.8.5, but C11 was introduced in 4.9.

解决办法
1、手动编译gcc大于4.9的版本
2、安装 devtoolset-9(使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC))编译安装Redis 6.0.5
yum install centos-release-scl -y
yum install devtoolset-9 -y

临时使用高版本gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC) (推荐使用这个方法)
export CC=/opt/rh/devtoolset-9/root/usr/bin/gcc
export CPP=/opt/rh/devtoolset-9/root/usr/bin/cpp
export CXX=/opt/rh/devtoolset-9/root/usr/bin/c++

wget http://download.redis.io/releases/redis-stable.tar.gz
tar zxf redis-stable.tar.gz && cd redis-stable
make -j2 && make install
if [ -f "/root/redis-stable/src/redis-server" ]; then
mkdir -p /usr/local/redis/{bin,etc,var}
/bin/cp /root/redis-stable/src/{redis-benchmark,redis-check-aof,redis-check-rdb,redis-cli,redis-sentinel,redis-server} /usr/local/redis/bin/
/bin/cp /root/redis-stable/redis.conf /usr/local/redis/etc/

cd /root/redis-stable/src
id -u redis >/dev/null 2>&1
[ $? -ne 0 ] && useradd -M -s /sbin/nologin redis

chown -R redis:redis /usr/local/redis/{var,etc}
#
if [ -e /bin/systemctl ]; then
cat > /lib/systemd/system/redis-server.service << "EOF"
[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
Type=forking
PIDFile=/var/run/redis/redis.pid
User=redis
Group=redis

Environment=statedir=/var/run/redis
PermissionsStartOnly=true
ExecStartPre=/bin/mkdir -p ${statedir}
ExecStartPre=/bin/chown -R redis:redis ${statedir}
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
ExecStop=/bin/kill -s TERM $MAINPID
Restart=always
LimitNOFILE=1000000
LimitNPROC=1000000
LimitCORE=1000000

[Install]
WantedBy=multi-user.target
EOF
systemctl enable redis-server

#确认Redis 6.0.5版本
[www@zhangfangzhou_cn ~]# redis-server -v
Redis server v=6.0.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=1987ac006866aa00

CentOS7.7安装 devtoolset-8(使用高版本gcc (GCC) 8.3.1 20190311)编译安装aria2-1.35.0
CentOS6安装devtoolset(使用高版本gcc)GCC 4.8 GCC 4.9 GCC 5.2

如何编译Linux Kernel(linux-5.6.12内核)并制作成rpm文件

如何编译内核及制作RPM包
CentOS 7 编译Linux Kernel(linux-5.6.12内核)并制作成rpm文件
1、下载Latest Stable Kernel
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.12.tar.xz
tar -Jxf linux-5.6.12.tar.xz

2、安装依赖包
yum -y install openssh-devel elfutils-libelf-devel bc

3、从 /boot 目录将现有版本的内核编译config配置文件拷过来到放到新的内核源码解压目录内并重命名为.config的隐藏文件(这个文件保存了在安装系统时内核所安装的模块配置信,否则需要重新手动指定每一个模块的编译配置)
cd linux-5.6.12
cp /boot/config-3.10.0-1062.el7.x86_64 ./.config
或者
cp /boot/config-$(uname -r) ./.config

3、安装开发工具包组
yum -y groupinstall "development tools"

4、安装ncurse-devel包 (make menuconfig 文本界面窗口依赖包)
yum -y install ncurses-devel
运行 make menuconfig,开启文本界面的编译选项菜单窗口,可以对内核加载的模块编译选项进行调整,如修改编译后的内核名称、新添加之前系统缺少的模块等
make menuconfig

(1)修改内核名称
General setup --->local version -append to kernel release #注意不要有空格

-----------
出现空格的话会产生错误错误
[root@www.zhangfangzhou.cn linux-5.6.12]# sudo make modules_install
ln: target ‘5.6.12_zhangfangzhou.cn_20200510/source’ is not a directory
make[1]: *** [_modinst_] Error 1
make: *** [sub-make] Error 2
-----------

(2)新添加NTFS文件系统支持模块
File systems --->DOS/FAT/NT Filesystems --->NTFS file system support

5、确认配置文件中NTFS功能是否添加成功
vi .config

6、编译内核 #时间较长,具体时间根据硬件性能决定
make -j `cat /proc/cpuinfo | grep 'model name'|wc -l`
或者
## get thread or cpu core count using nproc command ##
make -j $(nproc)

7、编译安装模块
编译完成后执行make modules_install 安装内核模块
make modules_install

8、安装内核核心文件
make install

9、制作成linux-5.6.12内核rpm文件
yum -y install rpmdevtools

cd linux-5.6.12
make rpm-pkg ##同时构建源和二进制RPM软件包
或者
make binrpm-pkg ##仅构建二进制RPM软件包

Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/kernel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64
Wrote: /root/rpmbuild/SRPMS/kernel-5.6.12_zhangfangzhou.cn_20200510-1.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-headers-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-devel-5.6.12_zhangfangzhou.cn_20200510-1.x86_64.rpm

10、CentOS 7 更换最新内核
egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \' #查看内核版本
grub2-set-default 0

reboot重启

11、Debian/Ubuntu 更换最新内核
sudo update-initramfs -c -k 5.6.12
sudo update-grub

12、查看内核版本
uname -msr
Linux 5.6.12_zhangfangzhou.cn_20200510 x86_64
----------
#https://linuxconfig.org/how-to-compile-vanilla-linux-kernel-from-source-on-fedora
#https://linuxhint.com/compile-linux-kernel-centos7/

百度云磁盘CDS Linux数据盘扩展分区

百度云磁盘CDS Linux数据盘扩展分区
随着Web业务的持续增加,原先400G的Web服务器数据磁盘已经不能满足使用,为满足Web业务的需要,决定扩容数据磁盘到1000G。
在百度云磁盘CDS扩容只是将磁盘的存储容量扩大,不会扩展分区和文件系统。

实战记录百度云磁盘CDS Linux数据盘扩展分区,Web 服务器为CentOS release 6.10 (Final)系统,数据磁盘的格式为EXT4。

1、查看Web服务器数据磁盘挂载信息
#mount | grep "/dev/vdb"
/dev/vdb1 on /data type ext4 (rw)

2、查看是否有程序在Web服务器数据磁盘正在运行
fuser -m /dev/vdb1
/dev/vdb1: 5115

如果有的话,查找并结束掉进程
ps aux | grep 5115
#ps aux | grep 5115
apache 5115 0.2 0.1 449060 29048 ? S 10:56 0:03 /usr/sbin/httpd

3、关闭正在使用Web服务器数据磁盘的服务或者进程
service httpd stop 或者 kill -9 5115

4、编辑fstab,取消Web服务器数据磁盘自动挂载
vi /etc/fstab
#/dev/vdb1 /data ext4 defaults 0 0

5、卸载Web服务器数据磁盘
#umount /dev/vdb1

#umount /dev/vdb1 如果有程序正在运行,则会这样提示
umount: /data: target is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
取消正在运行的程序 比如webserver mysql

6、调整分区大小
(1)查看分区表
fdisk /dev/vdb

p print the partition table
p
Command (m for help): p
Disk /dev/vdb: 1073.7 GB, 1073741824000 bytes
16 heads, 63 sectors/track, 2080507 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x2c594bf0

Device Boot Start End Blocks Id System
/dev/vdb1 1 2080507 1048575496+ 83 Linux

(2) 删除当前分区。当屏幕显示"已选择分区 1
d delete a partition
d

(3)新建分区
n add a new partition
n

(4)保存修改并退出
w write table to disk and exit
w
The partition table has been altered!

----------------------------
如果fstab有自动挂载则会出现这样的提示,需要提前执行第4步。
Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.
---------------------------
8、执行命令 lsblk /dev/vdb 查看当前文件系统是否已增加分区表
lsblk /dev/vdb
#lsblk /dev/vdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vdb 252:16 0 1000G 0 disk
└─vdb1 252:17 0 1000G 0 part /data

9、执行命令 e2fsck -n /dev/vdb1 查看当前文件系统的状态是否为 clean
e2fsck -n /dev/vdb1
如果有异常则会提示
/dev/vdb1 contains a file system with errors, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vdb1: 5641753/26214400 files (2.5% non-contiguous), 97404495/104857570 blocks

修复
fsck.ext4 -C0 /dev/vdb1

10、通知内核更新分区表 通知内核需同步数据盘的分区表信息。
yum -y install parted
partprobe /dev/vdb

11、完成文件系统扩展
resize2fs /dev/vdb1
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/vdb1 to 262142637 (4k) blocks.
The filesystem on /dev/vdb1 is now 262142637 blocks long.

Web服务器数据磁盘采用 ext4 文件系统,可以执行 resize2fs /dev/vdb1 命令以扩展文件系统大小。
对于 xfs 文件系统,需要先运行 mount /dev/vdb1 /data/ 命令,再运行xfs_growfs /dev/vdb1 以完成文件系统拓展。

12、编辑fstab,启用Web服务器数据磁盘自动挂载
vi /etc/fstab
/dev/vdb1 /data ext4 defaults 0 0

13、挂载全部
mount -a

14、确认文件系统扩展完毕
df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 20G 8.3G 11G 45% /
tmpfs tmpfs 12G 0 12G 0% /dev/shm
/dev/vdb1 ext4 985G 366G 569G 40% /data
/dev/vdc1 ext4 394G 270G 105G 73% /backup

---------------------------
https://cloud.baidu.com/doc/CDS/s/Lk0629a17

CentOS7.7安装 devtoolset-8(使用高版本gcc (GCC) 8.3.1 20190311)编译安装aria2-1.35.0

Aria2是一个支持HTTP/HTTPS, FTP, SFTP, BitTorrent和Metalink等协议的轻量级命令行下载工具。
编译安装aria2-1.35.0的时候出现错误,提示需要高版本gcc支持。
......
checking whether g++ supports C++11 features with -std=c++11 ... no
checking whether g++ supports C++11 features with -std=c++11 -stdlib=libc++... no
checking whether g++ supports C++11 features with -std=c++0x ... no
checking whether g++ supports C++11 features with -std=c++0x -stdlib=libc++... no
configure: error: *** A compiler with support for C++11 language features is required.
......

CentOS7.7默认的GCC版本为gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)
#gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39)
#cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

解决方法有两种
1、手动编译gcc>4.8的版本
自行编译
2、安装devtoolset-8(使用高版本gcc (GCC) 8.3.1 20190311
yum install centos-release-scl -y
yum install devtoolset-8 -y
启用devtoolset-8
#scl enable devtoolset-8 -- bash
#source /opt/rh/devtoolset-8/enable

临时编译前使用高版本gcc (GCC) 8.3.1 20190311 (推荐使用这个方法)
export CC=/opt/rh/devtoolset-8/root/usr/bin/gcc
export CPP=/opt/rh/devtoolset-8/root/usr/bin/cpp
export CXX=/opt/rh/devtoolset-8/root/usr/bin/c++
继续编译安装aria2-1.35.0
......

CentOS6安装devtoolset(使用高版本gcc)GCC 4.8 GCC 4.9 GCC 5.2

CentOS6安装devtoolset(使用高版本gcc)GCC 4.8 GCC 4.9 GCC 5.2

echo 0 > /proc/sys/kernel/hung_task_timeout_secs” disables this message.

tail /var/log/messages
echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
May 19 05:27:57 web kernel: Call Trace:
May 19 05:27:57 web kernel: [<ffffffff811d10a0>] ? sync_buffer+0x0/0x50
May 19 05:27:57 web kernel: [<ffffffff81549183>] io_schedule+0x73/0xc0
May 19 05:27:57 web kernel: [<ffffffff811d10e0>] sync_buffer+0x40/0x50
May 19 05:27:57 web kernel: [<ffffffff81549c6f>] __wait_on_bit+0x5f/0x90
May 19 05:27:57 web kernel: [<ffffffff811d10a0>] ? sync_buffer+0x0/0x50
May 19 05:27:57 web kernel: [<ffffffff81549d18>] out_of_line_wait_on_bit+0x78/0x90
May 19 05:27:57 web kernel: [<ffffffff810a6920>] ? wake_bit_function+0x0/0x50
May 19 05:27:57 web kernel: [<ffffffff811d1096>] __wait_on_buffer+0x26/0x30
May 19 05:27:57 web kernel: [<ffffffffa00707ef>] jbd2_journal_commit_transaction+0x117f/0x14f0 [jbd2]
May 19 05:27:57 web kernel: [<ffffffff8108fb2b>] ? try_to_del_timer_sync+0x7b/0xe0
May 19 05:27:57 web kernel: [<ffffffffa0075a38>] kjournald2+0xb8/0x220 [jbd2]
May 19 05:27:57 web kernel: [<ffffffff810a68a0>] ? autoremove_wake_function+0x0/0x40
May 19 05:27:57 web kernel: [<ffffffffa0075980>] ? kjournald2+0x0/0x220 [jbd2]
May 19 05:27:57 web kernel: [<ffffffff810a640e>] kthread+0x9e/0xc0
May 19 05:27:57 web kernel: [<ffffffff8100c28a>] child_rip+0xa/0x20
May 19 05:27:57 web kernel: [<ffffffff810a6370>] ? kthread+0x0/0xc0
May 19 05:27:57 web kernel: [<ffffffff8100c280>] ? child_rip+0x0/0x20
May 19 05:28:40 web kernel: end_request: I/O error, dev vdb, sector 564522839
May 19 05:33:42 web kernel: end_request: I/O error, dev vdb, sector 564522839
May 19 05:38:44 web kernel: end_request: I/O error, dev vdb, sector 564522839

进程等待IO时,经常处于D状态,即TASK_UNINTERRUPTIBLE状态,处于这种状态的进程不处理信号,所以kill不掉,如果进程长期处于D状态,那么肯定不正常,
原因可能有二
1)IO路径上的硬件出问题了,比如硬盘坏了(只有少数情况会导致长期D,通常会返回错误)
2)内核自己出问题了
这种问题不好定位,而且一旦出现就通常不可恢复,kill不掉,通常只能重启恢复了。
内核针对这种开发了一种hung task的检测机制。
基本原理是:定时检测系统中处于D状态的进程,如果其处于D状态的时间超过了指定时间(默认120s,可以配置),则打印相关堆栈信息,也可以通过proc参数配置使其直接panic。

1、查看是否存在坏块
/sbin/badblocks -v /dev/sdc

2、问题分析
May 19 05:27:57 web kernel: [<ffffffff811d10a0>] ? sync_buffer+0x0/0x50
May 19 05:27:57 web kernel: [<ffffffff81549183>] io_schedule+0x73/0xc0
May 19 05:27:57 web kernel: [<ffffffff811d10e0>] sync_buffer+0x40/0x50
May 19 05:27:57 web kernel: [<ffffffff81549c6f>] __wait_on_bit+0x5f/0x90

3、临时方案
根据应用程序情况,对vm.dirty_ratio,vm.dirty_background_ratio两个参数进行调优设置。
# sysctl -w vm.dirty_ratio=10
# sysctl -w vm.dirty_background_ratio=5
# sysctl -p

如果系统永久生效,修改/etc/sysctl.conf文件。
#vi /etc/sysctl.conf

vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

重启系统生效
http://www.361way.com/kernel-hung-task-analysis/4326.html

/dev/vda1 Inodes that were part of a corrupted orphan linked list found.

/dev/vda1 contains a file system with errors, check forced.
/dev/vda1 Inodes that were part of a corrupted orphan linked list found.
/dev/vda1 UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.

#检查文件系统
1、ext4文件系统
fsck -y /dev/vda1
或者
fsck.ext4 -a /dev/vda1

2、xfs文件系统
xfs_repair -n /dev/vda1 #检查文件系统是否损坏,只检查文件系统是否有损坏

fsck.ext4 [-panyrcdfvtDFV] [-b superblock] [-B blocksize]
[-I inode_buffer_blocks] [-P process_inode_size]
[-l|-L bad_blocks_file] [-C fd] [-j external_journal]
[-E extended-options] device

Emergency help:
-p Automatic repair (no questions)
-n Make no changes to the filesystem
-y Assume "yes" to all questions
-c Check for bad blocks and add them to the badblock list
-f Force checking even if filesystem is marked clean
-v Be verbose
-b superblock Use alternative superblock
-B blocksize Force blocksize when looking for superblock
-j external_journal Set location of the external journal
-l bad_blocks_file Add to badblocks list
-L bad_blocks_file Set badblocks list

Usage: xfs_repair [options] device
Options:
-f The device is a file
-L Force log zeroing. Do this as a last resort.
-l logdev Specifies the device where the external log resides.
-m maxmem Maximum amount of memory to be used in megabytes.
-n No modify mode, just checks the filesystem for damage.
-P Disables prefetching.
-r rtdev Specifies the device where the realtime section resides.
-v Verbose output.
-c subopts Change filesystem parameters - use xfs_admin.
-o subopts Override default behaviour, refer to man page.
-t interval Reporting interval in seconds.
-d Repair dangerously.
-V Reports version and exits.
https://support.microsoft.com/en-in/help/3213321/linux-recovery-cannot-ssh-to-linux-vm-due-to-file-system-errors-fsck

给CentOS6.x的GRUB 加密 和 CentOS7.x的GRUB2 加密

给CentOS6.x的GRUB 加密 和 CentOS7.x的GRUB2 加密

CentOS6.x GRUB 加密 (正常引导不需要密码,在启动项编辑GRUB需要输入密码)/boot/grub/grub.conf

通过在 grub.conf 中的启动配置中加入参数对grub进行加密:
1:加密的密码可以通过 grub-md5-crypt 生成
#grub-md5-crypt (回车,输入密码)
grub-md5-crypt
Password:
Retype password:
2:vi /boot/grub/grub.conf
3:在splashimage=(hd0,0)/grub/splash.xpm.gz后面 编辑插入 password --md5 $1$zoCS20$tuerHhzJGBVMdOA3uuQWZ0
4:在引导菜单修改引导配置的时候,则需要先输入密码,按p 输入密码

CentOS7.x GRUB2 加密 (正常引导不需要密码,在启动项编辑GRUB需要输入密码)/boot/grub2/grub.cfg
与CentOS6不同CentOS7采用的是grub2,而不是grub在CentOS7中,把grub的主要配置文件放在以下三个地方。
/boot/grub2/grub.cfg (/etc/grub2.cfg 是/boot/grub2/grub.cfg 文件的符号链接,lrwxrwxrwx. 1 root root 22 Sep 18 17:53 /etc/grub2.cfg -> ../boot/grub2/grub.cfg)
/etc/grub.d/ (ls /etc/grub.d/ 00_header 00_tuned 01_users 10_linux 20_linux_xen 20_ppc_terminfo 30_os-prober 40_custom 41_custom README)
/etc/default/grub (-rw-r--r--. 1 root root 197 Sep 18 17:54 /etc/default/grub)
这三个配置文件之间的关系是 grub.cfg 里通过 ####BEGIN ##### 这种格式按照顺序调用 /etc/grub.d 里面的脚本实现不同的功能,在grub.d 目录里有很多数字开头的脚本,按从小到大的顺序执行。

1、使用root用户生成grup2加密密码
grub2-mkpasswd-pbkdf2

2、 vi /etc/grub.d/01_users
cat <<EOF
set superusers="root"
password_pbkdf2 root grub.pbkdf2.sha512.10000.8A673CE3A2512ED267EB9E275B15D8430AECFAC29893EC278BF382EFCEB11FA5E3B679C8595F19BE2FAAC07C038B9C0CC4FF81462526BD1CFC98E15F75A4CC15.17D3A434DC8A97FCBB124CDCB7044F266164C647F0F917420128219E4B8FB62F9EDA9D9E6F4D9AC4F8F2D13565C803D347B631E18B2C231EE884563F345D3CF1
EOF

3、vi/etc/grub.d/01_linux
cat <<EOF
set superusers="zhangfangzhou"
password_pbkdf2 zhangfangzhou 生成的密码加密
EOF

4、最后执行grub2-mkconfig -o /boot/grub2/grub.cfg #重新生成GRUB配置文件 (Generate a GRUB configuration file.)