Neovim 全 Lua 配置
写这个是为了记录一下我新的VIM配置和VIM的快捷键,看起来lua的版本比之前的scripts要好的多, 无论是使用的方式还是启动的速度, 都比之前快。
我的需求:
打开代码, 会显示代码高亮。
vim可以默认满足的要求, 尽可能少的使用鼠标。
代码错误提示 LSP , 挂了Language Server. ( Already Config, but not work. Thinking About this.
主题, 目前使用的是 catppuccin-frappe
Markdown Preview ( Pending….
代码补全(Already Done.
我的快捷键清单:
Mappings
Actions
<Leader-1>
高亮第 1 列, 高亮列, 首字母缩进检查
<Leader-2>
高亮第 3 列, 高亮列, 双空格缩进检查
<Leader-3>
高亮第 5 列, 高亮列, 4空格缩进检查
<Leader-4>
高亮第 9 列, 高亮列, 8空格缩进检查
<Leader-a>
搭配Visual block mode 进行bash shell 的注释,行首添加#
<Leader-x>
同上,删除注释。
<Leader-r>
KubeApply (Fixed, Ready to use.)
<Leader-e>
KubeDelete (Fixed, Ready to use.)
<Leader-dr>
KubeApplyDIr (Fixed, Ready to use.)
<Leader-de>
KubeDeleteDir (Fixed, Ready to use.)
<Leader-ff>
Telescope Find FIles 查找文件
<Leader-fg>
Telescope Find Live grep 过滤文件中的关键字
<Leader-fb>
Telescope Find Buffer 查看Buffer中的数据。VIMbuffer
<Leader-fh>
Telescope Find Help( Maybe not use, Just record
<Leader-ps>
This is Alias for :PackerSync.
<Leader-ms>
This is Alias for :Mason.
<C-n>
Telescope PageDown 在Insert模式下面的上下移动。
<C-p>
Telescope PageUp 在Insert模式下面的上下移动。
<j / k>
Telescope NORMAL Up/Down Normal模式下的上下移动。
<C-x>
Telescope Go to file selection as a split 找到的文件直接水平开新窗口(下方
<C-v>
Telescope Go to file selection as a vsplit 找到的文件直接垂直开新窗口(右侧
<C-t>
Telescope Go to a file in a new tab 找到的文件开新的VIM tab, 感觉不是非常的好用,垂直会经常被用到。
<C-/>
Telescope Show mappings for picker actions (insert mode) 帮助
?
Telescope Show mappings for picker actions (normal mode) 帮助
<M-f>
Scroll left in results window
<M-b>
Scroll right in results window
其他的还在配置和学习中, 先这样把。。 之前用的功能不太多, 有时间继续看。。。。
About NerdFonts.Nerd 类型的字体实际代表了 带有Icon字符集的字体。https://www.nerdfonts.com/#home
其他技巧
不换行显示文本或者代码
set nowrap
直接grep文本的内容并替换当前buffer中的内容.是的,当前打开的文件在VIM里面其实是叫buffer, 因为并未完成实际的写入。
:%! grep KEYWORD
粘贴的时候保留格式。
set paste
set nopaste
或者是关闭autoindent
set ai
set noai
压缩多个空格为一个
:%s@ *@ @g
替换所有的空格 为 tab
:% s@ @\t@g
EC2 路由表以及多网卡相关问题
在EC2实例中, 可以使用多个不同的网卡, 但是虚拟网卡其实是共享实例整体带宽的。 假如EC2实例本身有10Gbps的带宽, 那么无论多少个网卡都应该只能有10Gbps的带宽, 其实添加了多个也不会扩展网络上限。
但是某些大规格的实例会有这种情况, 需要添加多个网卡,并且底层其实提供了多个NetworkCard。 这种情况少见, 但是确实有。
如果是物理的机器, 那么最好的办法就是链路聚合, 将多个网卡合并使用来扩充这个物理服务器的网络能力。
这样的实例添加网卡之后其实会有一定的难度,描述一下这个场景:
环境一台ec2 , 三张网卡, OS是 Ubuntu 18.04 , 三张网卡分别是 ens5 ens6 ens7 , 实例中命令展示网卡如下 :
root@ip-172-31-43-121:~# ip ad
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:4d:73:35:16:8a brd ff:ff:ff:ff:ff:ff
inet 172.31.43.121/20 brd 172.31.47.255 scope global dynamic ens5
valid_lft 1957sec preferred_lft 1957sec
3: ens6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:5d:02:b4:37:fa brd ff:ff:ff:ff:ff:ff
inet 172.31.37.95/20 brd 172.31.47.255 scope global dynamic ens6
valid_lft 1955sec preferred_lft 1955sec
4: ens7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:cf:10:d8:12:80 brd ff:ff:ff:ff:ff:ff
inet 172.31.40.130/20 brd 172.31.47.255 scope global dynamic ens7
valid_lft 1956sec preferred_lft 1956sec
三张网卡中, ens5上面有一个公网ip地址的绑定, elastic ip , 操作系统看不到, 但是ens5 能找到公网IP地址, 其他网卡都不能。
多网卡路由策略配置多网卡的情况下,手动配置了所有网卡的路由策略之后,公网访问没了, 看看 ip route show:
看路由表root@ip-172-31-43-121:~# ip r s
default via 172.31.32.1 dev ens7 proto dhcp src 172.31.40.130 metric 100
default via 172.31.32.1 dev ens6 proto dhcp src 172.31.37.95 metric 100
default via 172.31.32.1 dev ens5 proto dhcp src 172.31.43.121 metric 100
172.31.32.0/20 dev ens7 proto kernel scope link src 172.31.40.130
172.31.32.0/20 dev ens6 proto kernel scope link src 172.31.37.95
172.31.32.0/20 dev ens5 proto kernel scope link src 172.31.43.121
172.31.32.1 dev ens7 proto dhcp scope link src 172.31.40.130 metric 100
172.31.32.1 dev ens6 proto dhcp scope link src 172.31.37.95 metric 100
172.31.32.1 dev ens5 proto dhcp scope link src 172.31.43.121 metric 100
ip route show 命令显示的是系统路由表,也就是记录了目的网络和下一跳地址的信息的路由表。它的每个字段的含义是:
default 表示这个路由项是一个默认路由,也就是当没有匹配目的地址的路由项时,就使用这个路由项来发送数据包。
via 表示这个路由项的下一跳地址,也就是数据包要经过的网关地址。
dev 表示这个路由项对应的网卡设备名称,例如 lo, eth0, ens5 等。
proto 表示这个路由项的协议来源,例如 kernel, static, dhcp 等。
src 表示这个路由项的源地址,也就是本机发送数据包时使用的IP地址。
metric 表示这个路由项的度量值,也就是到达目的网络所需的跳数或开销。
这里面显示 我有三个默认路由, 他们的权重是一样的, 那么按照通常的逻辑, 哪个条目在靠前就会把数据包交给谁, 这时候问题出现了。
如果我的主网卡上面有公网IP地址, 这时候我去访问公网例如baidu, 会发现这个数据是出不去的, 因为默认匹配了第一个条目之后, 从 ens7 这个没有公网ip地址绑定的网卡走了。
看抓包测试一下, 直接开一个Ping命令在后台, ping www.baidu.com , 另一个窗口开 tcpdump -i any icmp看结果。
root@ip-172-31-43-121:~# tcpdump -i any icmp -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
14:49:31.480896 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 12, length 64
14:49:32.504867 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 13, length 64
14:49:33.528873 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 14, length 64
14:49:34.552872 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 15, length 64
14:49:35.576877 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 16, length 64
14:49:36.600873 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 17, length 64
14:49:37.624863 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 18, length 64
14:49:38.648871 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 19, length 64
14:49:39.672865 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 20, length 64
14:49:40.696876 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 21, length 64
14:49:41.720872 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 22, length 64
14:49:42.744873 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 23, length 64
14:49:43.768868 IP 172.31.40.130 > 39.156.66.14: ICMP echo request, id 15074, seq 24, length 64
能直接看到这个数据包是从 ens7 的网卡出去的, 确实匹配到了默认的路由条目, 第一条直接发走, 这本来是正确的逻辑, 但是一旦我需要访问公网且该实例的ens5才是公网ip的指定网卡, 那么这个数据包就只有出去, 没有回来的了。
这确实避免了VPC内部访问的网络限制问题, 但是公网的访问也没有了。 这是一个路由条目的优先级问题, 基于这个问题应该如何修复呢?
调整路由条目的优先级调整默认路由的优先级, 让数据匹配默认路由的时候优先匹配ens5的条目。
150 ip route del default via 172.31.32.1 dev ens5 proto dhcp src 172.31.43.121 metric 100
151 ip route add default via 172.31.32.1 dev ens5 proto dhcp src 172.31.43.121 metric 10
上面的命令可以将ens5 的默认路由metric 设置成 10 ,整体的路由表会变成这样:
root@ip-172-31-43-121:/etc/netplan# ip r s
default via 172.31.32.1 dev ens5 proto dhcp src 172.31.43.121 metric 10
default via 172.31.32.1 dev ens7 proto dhcp src 172.31.40.130 metric 100
default via 172 ...
Linux配置网卡策略路由
会遇到Linux多个网卡的时候, 网络并不会保证源地址进网卡 , 源地址出网卡。
大佬说, IP地址的其实关联的是操作系统,并不是特定的网卡, 所以对于os来说, 邻居子系统会选择一下网络数据从哪个物理网卡出。
这样就会导致,数据包会在网卡之间Forward一下,而转发出来的数据包, 会被aws vpc 丢包, 因为出入栈的地址不一样了。
对于这个行为, 需要配置操作系统的路由策略来解决, 让流量从相同的网卡进出。
记录一下这个配置。
UbuntuUbuntu 直接使用的netplan ,在配置文件里面直接指定policy就可以了。
配置文件位置: /etc/netplan/*
配置文件内容大致如下:
:~# cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
ethernets:
ens4:
dhcp4: true
dhcp6: false
match:
macaddress: 02:ab:8e:b1:ba:36
set-name: ens4
routes:
- to: 0.0.0.0/0
via: 172.31.48.1
table: 1000
- to: 172.31.51.248
via: 0.0.0.0
scope: link
table: 1000
routing-policy:
- from: 172.31.51.248
table: 1000
ens6:
dhcp4: true
dhcp6: false
match:
macaddress: 02:64:69:51:00:f2
set-name: ens6
routes:
- to: 0.0.0.0/0
via: 172.31.48.1
table: 1001
- to: 172.31.59.199
via: 0.0.0.0
scope: link
table: 1001
routing-policy:
- from: 172.31.59.199
table: 1001
version: 2
Redhat/CentOS/Fedora/AmazonLinux2旧方式设置设置开机配置路由的方式, 使用旧脚本得方式需要禁用NetworkManager,完全手动配置networkd的脚本。
安装旧的脚本管理工具
yum install -y network-scripts
确认配置文件是否正确
[root@ip-172-31-11-110 network-scripts]# ll
total 244
-rw-r--r--. 1 root root 174 Dec 17 12:30 ifcfg-eth0
-rw-r--r--. 1 root root 278 Dec 17 15:56 ifcfg-eth1
-rw-r--r--. 1 root root 254 Feb 15 2021 ifcfg-lo
-rwxr-xr-x. 1 root root 2123 Feb 15 2021 ifdown
-rwxr-xr-x. 1 root root 646 Feb 15 2021 ifdown-bnep
-rwxr-xr-x. 1 root root 6419 Feb 15 2021 ifdown-eth
-rwxr-xr-x. 1 root root 769 Feb 15 2021 ifdown-ippp
-rwxr-xr-x. 1 root root 4536 Feb 15 2021 ifdown-ipv6
lrwxrwxrwx. 1 root root 11 Feb 15 2021 ifdown-isdn -> ifdown-ippp
-rwxr-xr-x. 1 root root 2064 Feb 15 2021 ifdown-post
-rwxr-xr-x. 1 root root 870 Feb 15 2021 ifdown-routes
-rwxr-xr-x. 1 root root 1458 Feb 15 2021 ifdown-sit
-rwxr-xr-x. 1 root root 1621 Jul 26 2020 ifdown-Team
-rwxr-xr-x. 1 root root 1556 Jul 26 2020 ifdown-TeamPort
-rwxr-xr-x. 1 root root 1462 Feb 15 2021 ifdown-tunnel
-rwxr-xr-x. 1 root root 5463 Feb 15 2021 ifup
-rwxr-xr-x. 1 root root 12270 Feb 15 2021 ifup-aliases
-rwxr-xr-x. 1 root root 906 Feb 15 2021 ifup-bnep
-rwxr-xr-x. 1 root root 13776 Feb 15 2021 ifup-eth
-rwxr-xr-x. 1 root root 12068 Feb 15 2021 ifup-ippp
-rwxr-xr-x. 1 root root 11891 Feb 15 2021 ifup-ipv6
lrwxrwxrwx. 1 root root 9 Feb 15 2021 ifup-isdn -> ifup-ippp
-rwxr-xr-x. 1 root root 643 Feb 15 2021 ifup-plip
-rwxr-xr-x. 1 root root 1057 Feb 15 2021 ifup-plusb
-rwxr-xr-x. 1 root root 5000 Feb 15 2021 ifup-post
-rwxr-xr-x. 1 root root 2001 Feb 15 2021 ifup-routes
-rwxr-xr-x. 1 root root 3303 Feb 15 2021 ifup-sit
-rwxr-xr-x. 1 root root 1755 Jul 26 2020 ifup-Team
-rwxr-xr-x. 1 root root 1876 Jul 26 2020 ifup-TeamPort
-rwxr-xr-x. 1 root root 2879 Feb 15 2021 ifup-tunnel
-rwxr-xr-x. 1 root root 1836 Feb 15 2021 ifup-wireless
-rwxr-xr-x. 1 root root 5421 Feb 15 2021 init.ipv6-global
-rw-r--r--. 1 root root 20431 Feb 15 2021 network-functions
-rw-r--r--. 1 root root 31037 Feb 15 2021 network-functions-ipv6
-rw-r--r--. 1 root root 40 Dec 17 16:00 route-eth0
-rw-r--r--. 1 root root 40 Dec 17 16:00 route-eth1
-rw-r--r--. 1 root root 28 Dec 17 15:40 rule-eth0
-rw-r--r--. 1 root root 28 Dec 17 15:41 rule-eth1
书写文件内容,需要配置的文件如下:
[root@ip-172-31-11-110 network-scripts]$ cat ifcfg-eth0
# Created by cloud-init on instance boot automatically, do not edit.
#
BOOTPROTO=dhcp
DEVICE=eth0
HWADDR=02:20:22:29:a4:0c
ONBOOT=yes
STARTMODE=auto
TYPE=Ethernet
USERCTL=no
[root@ip-172-31-11-110 network-scripts]$ cat ifcfg-eth1
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=eth1
UUID=80caddf5-1347-4246-827e-5e0146c7f2c5
DEVICE=eth1
ONBOOT=yes
[root@ip-172-31-11-110 network-scripts]$ cat route-eth0
default via 172.31.0.1 dev eth0 table 1
[root@ip-172-31-11-110 network-scripts]$ cat route-eth1
default via 172.31.0.1 dev eth1 table 2
[root@ip-172-31-11-110 network-scripts]$ cat rule-eth0
from 172.31.11.110 lookup 1
[root@ip-172-31-11-110 network-scripts]$ cat rule-eth1
from 172.31.11.124 lookup 2
[root@ip-172-31-11-110 network-scripts]# cat /etc/iprout ...
Git常见的命令
远端创建, Clone本地Step 1Github上面创建一个新的仓库, 页面创建即可, 然后记录下URL。
https://github.com/LiarLee/vps-init.git
Step 2本地创建目录, 并初始化本地的仓库路径。
mkdir vps-init
cd ./vps-init
git clone https://github.com/LiarLee/vps-init.git
关联远端仓库创建一个本地仓库。
mkdir vps-init
cd ./vps-init
git init .
touch README
echo "For init server use DroneCI."
git add -A
git commit -m "init"
git remote add origin https://github.com/LiarLee/vps-init.git
git -u origin master
配置代理# 设置代理
ec2-user@arch ~> gitc config --global http.proxy socks5://1.1.1.1:7890
ec2-user@arch ~> git config --global https.proxy socks5://1.1.1.1:7890
# 取消代理
git config --global --unset http.proxy git config --global --unset https.proxy
取消git的特定文件追踪最好的办法是直接使用gitignore忽略这个文件, 但是开始创建仓库的时候可能想不到, 所以已经追踪的文件需要取消。
查看这个哪些文件会受到影响:
git rm -r -n --cached ./plugin
删除这些文件的追踪:
git rm -r --cached ./plugin
Linux Redhat 9 oom不触发
测试环境Amazon AMI ID: ami-0e54fe8afeb8fa59a
Operating System: Red Hat Enterprise Linux 9.2 (Plow)
Kernel: Linux 5.14.0-284.11.1.el9_2.x86_64
MySQL Version: Ver 8.0.33 for Linux on x86_64 (MySQL Community Server - GPL)
测试步骤:
使用上面的AMI启动一个新的实例, 在实例启动之后ssh连接进去。
按照MySQL官方的 repo 安装一个社区的版本。
# https://dev.mysql.com/downloads/repo/yum/
# (mysql80-community-release-el9-1.noarch.rpm)
wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
dnf install -y ./mysql80-community-release-el9-1.noarch.rpm
dnf makecache -y
dnf update -y
# Refer this doc to install mysql-community packages.
# https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html
dnf install -y mysql-community-server
# Check the installation success.
systemctl status mysqld
编辑MySQL配置文件, 添加如下的参数:
vim /etc/my.cnf
#设置buffer pool 的参数大于物理内存。 例如 os 本身由可用的内存是 16G, 那么设置一个更大的值即可。
innodb_buffer_pool_size = 40G
sudo systemctl enable --now mysqld
sudo systemctl status mysqld
# 获取root用户的临时初始化密码:
sudo grep 'temporary password' /var/log/mysqld.log
# 使用root用户登录, 并查看配置已经生效。
mysql -u root -p
MySQL [(none)]> show variables like "%buffer_pool_size%";
+-------------------------+-------------+
| Variable_name | Value |
+-------------------------+-------------+
| innodb_buffer_pool_size | 42949672960 |
+-------------------------+-------------+
1 row in set (0.005 sec)
创建database 以及 table:
create database test;
CREATE TABLE tt1(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
person_id tinyint not null ,
person_name1 VARCHAR(3000) ,
person_name2 VARCHAR(3000) ,
person_name3 VARCHAR(3000) ,
person_name4 VARCHAR(3000) ,
person_name5 VARCHAR(3000) ,
gmt_create datetime ,
gmt_modified datetime
) ;
insert into tt1 (person_id, person_name1, person_name2, person_name3, person_name4, person_name5, gmt_create, gmt_modified)
values (1, lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), now(), now());
# 反复执行这个命令, 复制全表的数据, 大概执行 10 次左右。
insert into tt1 (person_id, person_name1, person_name2, person_name3, person_name4, person_name5, gmt_create, gmt_modified)
select person_id, person_name1, person_name2, person_name3, person_name4, person_name5, now(), now() from tt1;
# 查看当前table的信息 ,确认一下数据量。
show table status like 'tt1'\G
在另一个机器上面 select 这个表格。
select count(*) from tt1;
如果数据量足够大的话, 那么就会占用超过物理内存的空间,导致OOM。
问题其他版本的os上面都会触发oom, 然后MySQL会被干掉重启, 只有Redhat 9 这个版本的os是不会触发的。
测试了Ubuntu 22, amazonlinux2, amazonlinux2023 都没由这个问题, 他们的内核都是 5.10+ 。
Redhat 9 这个版本的表现是, 在接近物理内存容量极限的时候, os 开始非常频繁的扫描并尝试回收内存的空间, 导致命令的响应变慢,我开了sar的监控命令,返回数据的速度也会便的比较慢, 大部分的进程会慢慢变成 Uninterreptable状态, 并且数量越来越多, 最终会导致实例的网络子系统不工作, 完全不响应任何的网络报文,实例的健康检查失败。CPU使用率依旧还在, EBS的监控显示这个卷满速度读取输出, 并且非常平稳, 响应时间以及队列的长度也没有异常。
如果这个时候尝试取手动触发oom, 是可以成功的, 在杀掉Mysqld之后, os就恢复了正常。
分析思路可以确定的是 磁盘的工作是正常的, CPU使用率慢慢增长但是也是正常的。 这部分的工作没有问题。
在发生问题的时候因为网络无法正常的工作,ssh已经断开, 无法确定当时的情况。
初步判断是内存的问题, 但是具体的差异是哪里。
第一sar命令中的记录
第二尝试对比与行为正常的os的差异, 获取sysctl -a 并记录到文件中。
对比完关于内存部分的参数, 完全没有任何的差别, 不是设置或者配置文件导致的这个问题。
min 水位的设置是默认的, 与其他的发行版本一直, 测试的时候用的相同的规格, 所以不存在这类的差异。
第三触发一个kdump 看看网络不相应的时候 os 当时的状态, 这个不太会。
第四查看内核的编译选项, 看看有什么不同。
第五学习os 内存的部分, 看看具体这个版本的内核如何进行内存的回收的, 或者触发oom的条件有哪些。
升级以及清理内核的步骤
通常情况下升级内核版本的步骤:
yum makecache -y
yum update -y
grub2-editenv list
grub2-set-default 'CentOS Linux (3.10.xxxxx.el7.elrepo.x86_64) 7 (Core)' # entry_name
systemctl reboot
清理旧版本的步骤;
rpm -qa kernel*
# 这个命令会列出所有当前已经安装的版本的内核, 然后手动使用命令移除对应的软件包即可。
# 我记得是有一个命令可以完全移除全部未使用的内核, 可能记错了, 这命令应该只有在ubuntu 上面是存在的。
yum groupinstall -y "Development Tools"
categories: Linux
yum install -y kernel kernel-devel kernel-debug
Linux内存管理笔记
内存管理部分的笔记Crash命令的使用使用这个命令需要有debuginfo 以及kernel debug 的数据包, 同时可能需要gdb。
需要在配置文件里面开启这个 仓库: rhel-8-baseos-rhui-debug-rpms
具体的步骤也可以看这个文档, 来自Redhat 官方: https://access.redhat.com/solutions/9907
yum install -y kernel-debuginfo
# 使用这个命令就可以安装, 但是尺寸非常的大。
crash /boot/vmlinuz-$(uname -a)
使用命令crash来进行 PM 和 VM的对应关系:
内核的debug文件在: /var/lib/debug/lib/modules/kernel-version/
使用crash命令:
~ # ❯❯❯ crash
crash 7.3.2-4.el8
Copyright (C) 2002-2022 Red Hat, Inc.
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
Copyright (C) 1999-2006 Hewlett-Packard Co
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
Copyright (C) 2005, 2011, 2020-2022 NEC Corporation
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions. Enter "help copying" to see the conditions.
This program has absolutely no warranty. Enter "help warranty" for details.
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
WARNING: kernel relocated [592MB]: patching 107327 gdb minimal_symbol values
KERNEL: /usr/lib/debug/lib/modules/4.18.0-477.13.1.el8_8.x86_64/vmlinux [TAINTED]
DUMPFILE: /proc/kcore
CPUS: 2
DATE: Tue Jul 11 17:07:01 CST 2023
UPTIME: 01:04:34
LOAD AVERAGE: 0.15, 0.03, 0.01
TASKS: 226
NODENAME: center
RELEASE: 4.18.0-477.13.1.el8_8.x86_64
VERSION: #1 SMP Thu May 18 10:27:05 EDT 2023
MACHINE: x86_64 (2199 Mhz)
MEMORY: 7.9 GB
PID: 7657
COMMAND: "crash"
TASK: ffff9ce7d835a800 [THREAD_INFO: ffff9ce7d835a800]
CPU: 0
STATE: TASK_RUNNING (ACTIVE)
crash> vm -p [pid]
PID: 913 TASK: ffff9ce7c75fd000 CPU: 0 COMMAND: "sshd"
MM PGD RSS TOTAL_VM
ffff9ce7c11b8000 ffff9ce7c75ae000 7604k 76644k
VMA START END FLAGS FILE
ffff9ce7c759f828 55a7fcc7b000 55a7fcd4c000 8000875 /usr/sbin/sshd
VIRTUAL PHYSICAL
55a7fcc7b000 12026b000
55a7fcc7c000 1201df000
55a7fcc7d000 1201ec000
55a7fcc7e000 1200c7000
55a7fcc7f000 120c43000
55a7fcc80000 10fa79000
55a7fcc81000 11fdd3000
55a7fcc82000 11087f000
55a7fcc83000 11fa8d000
55a7fcc84000 10fe05000
55a7fcc85000 110870000
55a7fcc86000 10fa2c000
55a7fcc87000 10f9fc000
55a7fcc88000 10fdab000
55a7fcc89000 11f296000
55a7fcc8a000 1117ec000
55a7fcc8b000 10fdac000
55a7fcc8c000 120c65000
55a7fcc8d000 12011b000
55a7fcc8e000 110714000
55a7fcc8f000 110c83000
55a7fcc90000 110c90000
55a7fcc91000 110d2b000
55a7fcc92000 120730000
55a7fcc93000 12076f000
55a7fcc94000 1207e8000
55a7fcc95000 110c2f000
55a7fcc96000 110c3c000
55a7fcc97000 120650000
55a7fcc98000 1206c1000
55a7fcc99000 120c67000
55a7fcc9a000 120c0f000
55a7fcc9b000 FILE: /usr/sbin/sshd OFFSET: 20000
55a7fcc9c000 11d46d000
55a7fcc9d000 10fe01000
55a7fcc9e000 10fdb9000
55a7fcc9f000 10fde7000
55a7fcca0000 FILE: /usr/sbin/sshd OFFSET: 25000
# 结果省略了后面的部分, 太长了。。 。。
可以看到内存的映射关系, notmapped 表示没有被映射到物理内存的部分。
一般来说 后面的三位是一样的, 如果是THP的话, 那么后面的五位是一样的。
这个vtop 可以直接查看里面保存的内容以及具体的映射关系。
crash> vtop 55d5473fc000
VIRTUAL PHYSICAL
55d5473fc000 (not accessible)
rd命令可以读取指定的内存虚拟地址之后的偏移量。
crash> rd 55d54879d000 100
rd: invalid user virtual address: 55d54879d000 type: "64-bit UVADDR"
超过内存申请容量的使用, 会导致 访问内存越界, 例如申请了1G的内存,但是尝试写入超出的数据量, 会导致数据写到后续不属于这个进程的空间上, 而这个时候内核会触发一个 segfault, 来终止这个进程。
这个报错不是立刻发生的,可能确实会溢出一部分。
匿名页面 实际上是 mmap with MAP_ANONYMOUS flag映射出来的虚拟内存地址, 当需要第一次去写匿名页面的时候, 会将物理内存的地址映射到虚拟内存并将其中填0.
overcommit 0 可以所有的地址, 1 无限制,虚拟内存没有限制, 2 按照一定的比例进行计算, 最终的结果。
添加一个Redhat到EKS集群, 基于Packer的步骤
Copy From zhojiew 的私有仓库文档, 已经经过授权 ~
官方提供了基于packer工具的构建脚本
这里手动把相关的步骤执行下,基于redhat9构建一个自定义ami。据称eks优化的ami也是通过以下步骤完成的
手动构建ami拉仓库
cd /home/ec2-suer
sudo yum install git -y
git clone https://github.com/awslabs/amazon-eks-ami.git
配置环境变量
KUBERNETES_VERSION=1.26.4
KUBERNETES_BUILD_DATE=2023-05-11
BINARY_BUCKET_NAME=amazon-eks
BINARY_BUCKET_REGION=cn-north-1
DOCKER_VERSION=20.10.23-1.amzn2.0.1
CONTAINERD_VERSION=1.6.*
RUNC_VERSION=1.1.5-1.amzn2
CNI_PLUGIN_VERSION=v0.8.6
PULL_CNI_FROM_GITHUB=true
SONOBUOY_E2E_REGISTRY=""
PAUSE_CONTAINER_VERSION=3.5
CACHE_CONTAINER_IMAGES=false
WORKING_DIR=/tmp/worker
TEMPLATE_DIR=/home/ec2-user/amazon-eks-ami
复制文件更新内核(可以跳过)
mkdir -p $WORKING_DIR
mkdir -p $WORKING_DIR/log-collector-script
mkdir -p $WORKING_DIR/bin
mv $TEMPLATE_DIR/files/* $WORKING_DIR/
mv $TEMPLATE_DIR/log-collector-script/linux/eks-log-collector.sh $WORKING_DIR/log-collector-script/
sudo chmod -R a+x $WORKING_DIR/bin/
sudo mv /tmp/worker/bin/* /usr/bin/
# sudo bash $TEMPLATE_DIR/scripts/upgrade_kernel.sh
KERNEL_VERSION=5.10
sudo grubby \
--update-kernel=ALL \
--args="psi=1"
sudo grubby \
--update-kernel=ALL \
--args="clocksource=tsc tsc=reliable"
sudo reboot
构建的主要逻辑在脚本install-worker.sh中
# sudo bash $TEMPLATE_DIR/scripts/install-worker.sh
export AWS_DEFAULT_OUTPUT="json"
ARCH="amd64"
sudo yum update -y
sudo yum install -y \
chrony \
conntrack \
curl \
ethtool \
ipvsadm \
jq \
nfs-utils \
socat \
unzip \
wget \
yum-utils \
yum-plugin-versionlock \
mdadm \
pigz
# Remove any old kernel versions.
sudo package-cleanup --oldkernels --count=1 -y
# Remove the ec2-net-utils package
if yum list installed | grep ec2-net-utils; then sudo yum remove ec2-net-utils -y -q; fi
sudo mkdir -p /etc/eks/
sudo mv $WORKING_DIR/configure-clocksource.service /etc/eks/configure-clocksource.service
# iptables
sudo mv $WORKING_DIR/iptables-restore.service /etc/eks/iptables-restore.service
# awscli
sudo yum install less unzip jq -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --update
complete -C '/usr/local/bin/aws_completer' aws
# systemd
sudo mv "${WORKING_DIR}/runtime.slice" /etc/systemd/system/runtime.slice
编译安装runc
# install runc and lock version
# sudo yum install -y runc-${RUNC_VERSION}
sudo yum install libseccomp-devel.x86_64 golang -y
go env -w GOPROXY=https://goproxy.io,direct
git clone https://github.com/opencontainers/runc
cd runc
make
sudo make install
安装containerd
# install containerd and lock version
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# sudo yum install -y containerd-${CONTAINERD_VERSION}
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y containerd # 1.6.21
配置containerd
sudo mkdir -p /etc/eks/containerd
sudo mv $WORKING_DIR/containerd-config.toml /etc/eks/containerd/containerd-config.toml
# containerd and related service
sudo mv $WORKING_DIR/kubelet-containerd.service /etc/eks/containerd/kubelet-containerd.service
sudo mv $WORKING_DIR/sandbox-image.service /etc/eks/containerd/sandbox-image.service
sudo mv $WORKING_DIR/pull-sandbox-image.sh /etc/eks/containerd/pull-sandbox-image.sh
sudo mv $WORKING_DIR/pull-image.sh /etc/eks/containerd/pull-image.sh
sudo chmod +x /etc/eks/containerd/pull-sandbox-image.sh
sudo chmod +x /etc/eks/containerd/pull-image.sh
sudo mkdir -p /etc/systemd/system/containerd.service.d
cat << EOF | sudo tee /etc/systemd/system/containerd.service.d/10-compat-symlink.conf
[Service]
ExecStartPre=/bin/ln -sf /run/containerd/containerd.sock /run/dockershim.sock
EOF
cat << EOF | sudo tee -a /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
cat << EOF | sudo tee -a /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# skip docker
日志轮换配置
# logrotate
sudo mv $WORKING_DIR/logrotate-kube-proxy /etc/logrotate.d/kube-proxy
sudo mv $WORKING_DIR/logrotate.conf /etc/logrotate.conf
sudo chown root:root /etc/logrotate.d/kube-proxy
sudo chown root:root /etc/logrotate.conf
sudo mkdir -p /var/log/journal
下载kubelet和aws-iam-authenticator
## download bin in china region
S3_DOMAIN="amazonaws.com.cn"
S3_PATH="s3://amazon-eks/1.26.4/2023-05-11/bin/linux/amd64"
# Verify that the aws-iam-authenticator is at last v0.5.9 or greater
BINARIES=(
kubelet
aws-iam-authenticator
)
for binary in ${BINARIES[*]}; do
aws s3 cp $S3_PATH/$binary . --region cn-north-1
sudo chmod +x $binary
sudo mv $binary /usr/bin/
done
继续配置服务
# kubernetes
sudo mkdir -p /etc/kubernetes/manifests
sudo mkdir -p /var/lib/kubernetes
sudo mkdir -p /var/lib/kubelet
sudo mkdir -p /opt/cni/bin
CNI_PLUGIN_FILENAME="cni-plugins-linux-${ARCH}-${CNI_PLUGIN_VERSION}"
aws s3 cp --region $BINARY_BUCKET_REGION $S3_PATH/${CNI_PLUGIN_FILENAME}.tgz .
su ...
BufferIO与DirectIO的比较
测试方法使用BufferIO的方式, 测试文件的写入:
#!/bin/bash
perf record -T -C 0 -- taskset -c 0 dd if=/dev/zero of=./a.dat bs=4k count=16384
使用DirectIO的方式, 测试文件的写入:
#!/bin/bash
perf record -T -C 0 -- taskset -c 0 dd if=/dev/zero of=./a.dat bs=4k count=16384 oflag=direct
运行结果BufferIO:
[root@ip-172-31-53-200 perf_records]# ./start_test_bufferio.sh
16384+0 records in
16384+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 0.118848 s, 565 MB/s
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.225 MB perf.data (485 samples) ]
ll -h
-rw-r--r--. 1 root root 64M Jun 1 13:45 a.dat
[root@ip-172-31-53-200 ~]# dstat -tf
----system---- -----cpu0-usage----------cpu1-usage----------cpu2-usage----------cpu3-usage---- dsk/nvme0n1 ---net/lo-----net/eth0- ---paging-- ---system--
time |usr sys idl wai stl:usr sys idl wai stl:usr sys idl wai stl:usr sys idl wai stl| read writ| recv send: recv send| in out | int csw
01-06 13:35:48| 2 0 99 0 0: 1 0 99 0 0: 0 1 98 0 0: 1 0 99 0 0|8192B 35k|1096B 1096B: 968B 828B| 0 0 | 712 971
01-06 13:35:49| 25 9 60 5 0: 0 0 99 0 0: 4 12 84 0 0: 4 8 90 0 0| 0 64M|1096B 1096B: 576B 756B| 0 0 |2283 1311
01-06 13:35:50| 6 1 94 0 0: 1 1 99 0 0: 16 2 83 0 0: 0 1 99 0 0| 0 0 |1096B 1096B: 156B 418B| 0 0 | 954 1018
DirectIO:
[root@ip-172-31-53-200 perf_records]# ./start_test_directio.sh
16384+0 records in
16384+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 10.4225 s, 6.4 MB/s
[ perf record: Woken up 9 times to write data ]
[ perf record: Captured and wrote 2.417 MB perf.data (41489 samples) ]
[root@ip-172-31-53-200 ~]# dstat -tf
----system---- -----cpu0-usage----------cpu1-usage----------cpu2-usage----------cpu3-usage---- dsk/nvme0n1 ---net/lo-----net/eth0- ---paging-- ---system--
time |usr sys idl wai stl:usr sys idl wai stl:usr sys idl wai stl:usr sys idl wai stl| read writ| recv send: recv send| in out | int csw
01-06 13:36:36| 0 1 99 0 0: 1 1 99 0 0: 0 1 100 0 0: 0 1 100 0 0| 0 0 |1097B 1097B: 688B 624B| 0 0 | 622 930
01-06 13:36:37| 3 4 32 61 0: 4 14 81 0 0: 1 0 97 0 0: 0 5 94 0 0| 0 4277k|1095B 1095B: 332B 338B| 0 0 |6434 3133
01-06 13:36:38| 3 3 0 92 0: 1 1 99 0 0: 3 1 96 0 0: 0 0 99 0 0| 0 6421k|1096B 1096B: 52B 174B| 0 0 |8767 4148
01-06 13:36:39| 4 4 0 92 0: 0 0 99 0 0: 4 1 96 0 0: 2 0 100 0 0| 0 6431k|1096B 1096B: 52B 150B| 0 0 |8790 4191
01-06 13:36:40| 4 4 0 91 0: 0 1 99 0 0: 2 1 96 0 0: 0 1 99 0 0| 0 6320k|1096B 1096B: 52B 142B| 0 0 |8744 4092
01-06 13:36:41| 4 4 0 92 0: 1 0 99 0 0: 3 0 96 0 0: 0 0 100 0 0| 0 6216k|1096B 1096B: 52B 142B| 0 0 |8662 4103
01-06 13:36:42| 3 4 0 92 0: 1 1 99 0 0: 2 2 96 0 0: 0 0 99 0 0| 0 7492k|1576B 1576B: 52B 134B| 0 0 |8756 4099
01-06 13:36:43| 3 3 0 91 0: 1 0 99 0 0: 4 1 96 0 0: 0 0 100 0 0| 0 6284k|1096B 1096B: 52B 134B| 0 0 |8720 4077
01-06 13:36:44| 4 2 0 92 0: 0 0 99 0 0: 2 1 96 0 0: 0 0 99 0 0| 0 6296k|1096B 1096B: 52B 134B| 0 0 |8788 4067
01-06 13:36:45| 4 5 0 91 0: 1 0 99 0 0: 4 0 96 0 0: 1 0 99 0 0| 0 6368k|1096B 1096B: 52B 134B| 0 0 |8792 4071
01-06 13:36:46| 3 5 0 92 0: 1 1 99 0 0: 4 1 96 0 0: 0 0 100 0 0| 0 5904k|1096B 1096B: 52B 134B| 0 0 |8576 3893
01-06 13:36:47| 25 7 0 69 0: 0 0 99 0 0: 2 1 96 0 0: 0 0 100 0 0| 0 4811k|1097B 1097B: 364B 763B| 0 0 |7035 3360
01-06 13:36:48| 4 0 96 0 0: 1 0 99 0 0: 22 3 75 1 0: 0 1 100 0 0|2642k 109k|1095B 1095B: 208B 472B| 0 0 | 977 1008
01-06 13:36:49| 0 1 99 0 0: 0 0 100 0 0: 0 0 98 0 0: 0 0 99 0 0| 0 0 |1096B 1096B: 104B 276B| 0 0 | 640 903
Perf 采样结果BufferIO:
DirectIO:
VPCFlowlog解析
记录VPC Flow Log 怎么看https://docs.amazonaws.cn/vpc/latest/userguide/flow-logs.html#flow-log-recordshttps://docs.amazonaws.cn/vpc/latest/userguide/flow-logs-records-examples.html#flow-log-example-tcp-flag
vpc flow log里的tcp-flags记录的不是某个单个tcp包头里的flag,而是单次观察的时间窗口里这条flow的所有tcp包出现过的tcp flag的合计。
TCP flags can be OR-ed during the aggregation interval. For short connections, the flags might be set on the same line in the flow log record, for example, 19 for SYN-ACK and FIN, and 3 for SYN and FIN. For an example, see TCP flag sequence.For general information about TCP flags (such as the meaning of flags like FIN, SYN, and ACK), see TCP segment structureon [Wikipedia].
这个记录里面的值, 是这样计算出来的, 从右向左 , 从 0 次方开始计算。
FIN 2^0
SYN 2^1
RST 2^2
PSH 2^3
ACK 2^4
URG 2^5
ECE 2^6
CWR 2^7