avatar
文章
155
标签
73
分类
16

Home
Archives
Link
About
Liarlee's Notebook
搜索
Home
Archives
Link
About
buffer/cache 无法释放
发表于2023-05-12|更新于2025-05-10|Linux
问题看到了一个案例, 这个案例的问题是: 为什么我的buffer/cache在echo 3 之后, 还是不能回收, 内存的占用很大。 命令如下: root@ip-172-31-47-174 ~# free -h total used free shared buff/cache available Mem: 7.5Gi 1.3Gi 3.5Gi 2.1Gi 2.6Gi 3.8Gi Swap: 0B 0B 0B root@ip-172-31-47-174 ~# echo 3 > /proc/sys/vm/drop_caches root@ip-172-31-47-174 ~# free -h total used free shared buff/cache available Mem: 7.5Gi 1.3Gi 3.7Gi 2.1Gi 2.4Gi 3.9Gi Swap: 0B 0B 0B root@ip-172-31-47-174 ~# free total used free shared buff/cache available Mem: 7833520 1376608 3917368 2160524 2539544 4059944 Swap: 0 0 0 分析和答案分析: 开始的时候我并没有发现具体有什么问题, 认为是应用程序确实无法回收cache的空间,因为正在使用。 例如Firefox启动的时候就会使用Cache的空间来进行数据的存储。 答案: 第二天看到了大佬的更新, 这个问题的原因是: 内核会将 shared 的空间, 一并统计在 buffer/cache 中, 所以free命令的输出是正常的, 实际cache已经释放了一部分,没有大幅度变化的原因是因为那部分是 shmem的空间, 所以。。。释放不掉。 初见这个结论是有些震惊的, 我一直都认为 shared 字段里面统计的内存是独立的, 仔细看看上面的命令, 确实 shared空间基本上与 buffer/cache的空间是差不多的。 测试一部分信息: OS: Arch Linux x86_64 Kernel: 6.3.1-arch2-1 Software Version: free from procps-ng 3.3.17 测试的方法, 我只是尝试证明free命令的统计方式变化, 所以直接简化了, 直接扩大ShareMemory。 # 直接创建一个临时的目录 # 其实直接使用 /dev/shm 也行, 但是可用空间会被限制到 物理内存的一半。 sudo mkdir /mnt/tmpfs/ # 挂载到 /mnt/tmpfs/ sudo mount -t tmpfs -o size=5000m shared /mnt/tmpfs/ # 创建一个文件占用那个部分的内存。 sudo fallocate -l 4G /mnt/tmpfs/file 按照上面的步骤测试, 可以发现 share memory 确实也同时被统计在了 buffer/cache 里面, 与客户的现象完全一致。这个命令确实就是这样工作的。 按照这个思路应该看看meminfo 以及 内核的文档,Mark一下准备开始走一遍这个思路。 立刻查看free命令的manpage, 发现果然没有更新, 说明摘要: sharedMemory used (mostly) by tmpfs (Shmem in /proc/meminfo) buffersMemory used by kernel buffers (Buffers in /proc/meminfo) cacheMemory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo) buff/cacheSum of buffers and cache 看 /proc/meminfo , 发现确实是取值取到了 shmem, 这个值是对的, 现在的问题就是为什么内核提供了这样的一个值。 sudo cat /proc/meminfo | grep -Ei "mem|cache|buffer|active" MemTotal: 7833520 kB MemFree: 4417692 kB MemAvailable: 4615060 kB Buffers: 0 kB Cached: 2550368 kB # 这个的统计就。。。。 free是对的 SwapCached: 0 kB Active: 830560 kB Inactive: 2397160 kB Active(anon): 444220 kB Inactive(anon): 2385016 kB Active(file): 386340 kB Inactive(file): 12144 kB Shmem: 2151884 kB # 这个是创建的文件大小,转换成文件的大小, 差不多是 2G 左右。 现在的问题变成, 具体是什么时候 meminfo里面的值变更了统计方式呢? 为什么这样统计呢? 不会找具体是什么时候commit的变更, 直接看代码吧。 希望我看的是对的。 // https://elixir.bootlin.com/linux/latest/source/fs/proc/meminfo.c static int meminfo_proc_show(struct seq_file *m, void *v) { struct sysinfo i; ... cached = global_node_page_state(NR_FILE_PAGES) - total_swapcache_pages() - i.bufferram; if (cached < 0) cached = 0 ... show_val_kb(m, "MemTotal: ", i.totalram); show_val_kb(m, "MemFree: ", i.freeram); show_val_kb(m, "MemAvailable: ", available); show_val_kb(m, "Buffers: ", i.bufferram); show_val_kb(m, "Cached: ", cached); show_val_kb(m, "SwapCached: ", total_swapcache_pages()); show_val_kb(m, "Active: ", pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]); show_val_kb(m, "Inactive: ", pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]); show_val_kb(m, "Active(anon): ", pages[LRU_ACTIVE_ANON]); show_val_kb(m, "Inactive(anon): ", pages[LRU_INACTIVE_ANON]); show_val_kb(m, "Active(file): ", pages[LRU_ACTIVE_FILE]); show_val_kb(m, "Inactive(file): ", pages[LRU_INACTIVE_FILE]); show_val_kb(m, "Unevictable: ", pages[LRU_UNEVICTABLE]); show_val_kb(m, "Mlocked: ", global_zone_page_state(NR_MLOCK)); 可以看到从一个sysinfo 的 struct 取出, 然后进行计算, 存储在cached 变量里面,然后输出: // https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/sysinfo.h#L14 __kernel_ulong_t bufferram; /* Memory used by buffers */ 好了 我看不动了,Cached 的最后结果: os所有可用的文件页面 - SwapCached的数值 - Buffers的数值,大概应该是这个意思, 按照这么算的话, 确实会加入 shmem 的部分,邮件归档以及解释 That’s a reasonable position to take. Another point of view is that everything in tmpfs is part of the page cache and can be written out to swap, so keeping it as part of Cached is not misleading. I can see it both ways, and personally, I’d lean towards clarifyingthe documentation about how shmem is accounted rather than changing how the memory usage is reported. 这是上面的邮件链接中的一部分, 解释了为什么将 shmem 计算到 Cached 中的原因,看起来现在应该由一个新的指标数值来处理这个了。 更多的部分看参考链接吧,我顺便看了讲解,大佬讲的清楚。 参考链接https://zhuanlan.zhihu.com/p/586107891 https://www.cnblogs.com/tsecer/p/16290025.html
RDS QPS 下降引发的网络流控分析记录
发表于2023-05-09|更新于2025-05-10|Linux
找到了另一个大佬对于TCP在linux内核的分析和测试: Link Topic 1 现象看到一个朋友的问题, 由 RDS QPS 下降引发的网络问题分析: 引用原文的问题描述: 这个问题一开始是在进行RDS实验的时候发现的。最初的情景是,多台机器同时对数据库进行select和insert操作时,会发现insert操作会造成select操作qps大幅下降,且insert操作结束之后select操作的qps仍不能回升。起初以为是RDS的问题,但是在复现问题、监控RDS之后发现RDS的压力其实很小。于是开始怀疑是网络的问题,在简化了场景和操作之后,发现能在过去做tcp实验的机器上复现,于是用这个更简单的场景进行问题复现和分析。 正确答案以及复盘: https://yishenggong.com/2023/05/06/why-does-my-network-speed-drop-cn/ 感谢大佬@plantegg 提供的这个案例和知识星球, tcp协议和 os 网络系统的分析我之前真是一句都说不出来, 这次确实完整的走了一遍网络的部分。 下面是我的一些思路和资料整理: 看完了问题的描述, 我基本上可以给出一个经验的判断,这个问题是aws t2实例的流控, 因为表现和之前的测试非常一致, 为了确认这个问题我又进行了相关的测试,基准信息如下: 实例类型:t2.micro 实例的基准带宽: 64Mbps 实例的突增带宽: 1Gbps 实例的EBS规格: 3000 IOPS, 100GB根卷存储, 125MiB/s 实例的OS : AmazonLinux2023. Congestion: Cubic 具体的测试方法: 启动4个实例 t2.micro, hostname 分别是 nginx \ client1 \ client2 , 方便测试和区分实例; 启动一个额外的实例Client3 来尝试验证是不是流控。 nginx上面启动一个Nginx server, 发布一个 2GB 大小的文件; Client 1、 Client2 两个实例上面使用curl命令下载。 尝试保持这个流量一段时间之后, 带宽会被限制到64 Mbps。 由于是流控的问题, 所以现象会稳定出现。 Summary: 我理解这个应该是一个对tcp流的限制, 所以验证这个问题的方法是启动一个iperf的服务并重新生成流量, 如果是流控的话, 那么新的流量应该不受限制, 简单的证明方式就是在Nginx Server上面启动一个Iperf3 的 Server , 然后在发生降低速度的时刻, 使用 Client3 iperf 测试 Nginx Server, 这个时候观察到的现象是两个原有网络链接的速度还是很低, 但是iperf3 的测试网络吞吐量是比较高的。 t系列的实例都是突增类型, 可以允许一定的时间使用超过实例基准性能的资源, 在网络流量超过基准性能一段时间之后, 实例的带宽会被限制。 之前真的一直都没有思考过实例的带宽限制都是怎么做的, 让我在描述更多的细节我也确实无法提供, 借着这个机会,深入研究一下。 重新开始分析这个问题: 分析网络抓包看看,被限速的是Server的实例, 所以直接看Server的抓包. 贴一个我自己抓包截图,两个不同的流: Server to Client 1: Server to Client 2: 对与上面的两个截图来看, 斜率表越大,下载速度越快, 在斜率较大的前半段, 并未发生任何的TCP异常; 后半段斜率变小的期间,一直有规律的红色标记, 那个标记对应到抓包的结果中,是快速重传的数据包, 并且发生快速重传的时间比较规律, 这类规律的快速重传影响了传输的速度。 查看RTT的变化, 截图如下: Server to Client 1: Server to Client 2: 上面的这个部分可以看出整体增大了RTT ,基于之前的tc流控测试,rtt增大的链路上, 发送和接收的窗口需要相应的增大, 才能保证带宽的利用率较高。 按照实验更增加 wmem 和 rmem, 三个实例的设置都增加, 增加之后的速度并没有改变, 依旧还是被限制的水平。RTT从抓包的结果上面来看就是有明显的变化。 查看Server 实例的CWND, 这个CWND的记录直接使用命令行看: 左侧是Server上面的命令行执行结果 命令是 ss -4tni , 命令输出的结果中, 有当前的TCP链接的 RTT, CWND的值, 可以观察到, 到两个Server的链接中RTT的值 ~60ms 左右, 我使用了watch 0.1s来执行ss命令和观察, 重点关注上面的几个参数, 可以发现这几个数值的范围如下: RTT ~ 50ms ~ 70ms 之间变化的频率基本上与cwnd的变化频率一致。 CWND 40 - 64 之间变化, 到达64之后回落到40左右, 然后快速提高到64再回落。 引用一个描述比较清晰的中文文章,其中也介绍了常见的几种拥塞控制算法的模式, 帮我大概理解了下网络的部分: TCP 连接建立后先经过 Slow Start 阶段,每收到一个 ACK,CWND 翻倍,数据发送率以指数形式增长,等出现丢包,或达到 ssthresh,或到达接收方 RWND 限制后进入 Congestion Avoidance 阶段。1 从另一个文章中找到了如下的一个公式: 因此想要充分利用带宽,必须让窗口大小接近 BDP 的大小,才能确保最大吞吐量。 我们通过如下的例子来讨论一下,究竟 rwnd 和 cwnd 的值与理论最大使用带宽的关系是什么? min(cwnd, rwnd) = 16 KB RTT = 100 ms 16 KB = 16 X 1024 X 8 = 131072 bits 131072 / 0.1 = 1310720 bits/s 1310720 bits/s = 1310720 / 1000000 = 1.31 Mbps 因此,无论发送端和接收端的实际带宽为多大,当窗口大小为 16 KB 时,传输速率最大只能为 1.31 Mbps 。2 可以看到上面的公式中的第一个, 在计算的时候会在cwnd, rwnd 两个指标中选取最小的生效, 那么基于上面的变动, 我们已经把wmem , rmem 都改到了较大的值, 那么这个时候较小 的就是 cwnd 了, 这个值增加不上去就无法充分的利用带宽。 那么现在的问题变成了为什么 cwnd 无法继续增长? Cubic 在 BIC 的基础上,一个是通过三次函数去平滑 CWND 增长曲线,让它在接近上一个 CWND 最大值时保持的时间更长一些,再有就是让 CWND 的增长和 RTT 长短无关,即不是每次 ACK 后就去增大 CWND,而是让 CWND 增长的三次函数跟时间相关,不管 RTT 多大,一定时间后 CWND 一定增长到某个值,从而让网络更公平,RTT 小的连接不能挤占 RTT 大的连接的资源。1 如果cwnd的大小在拥塞避免之后是基于时间来进行增长的,那么就可以结合上面我观察到的现象, 基本上过一段时间就会出现一定量的快速重传(抓包结果), 周期性的RTT 与 cwnd的变化(命令输出结果)比较吻合了。 基于上面的命令输出结果可以认为确实是通过RTT的增加 + 丢包控制 CWND, 压着CWND的值上不去的原因就是快速重传, 让cwnd随时间增大之后快速重传, 然后触发拥塞避免, 回退到较低的值, 然后开始循环。 感谢Shuo Chen 和 Hao Chen 大佬的测试分析思路以及工具,反复的理解这个Thread里面的说法, 现在基本上可以抓住这个问题的逻辑了。 走着一圈之后, 写完了上面自己的总结, 现在复制大佬的答案: @bnu_chenshuo 从发生 retransmit 的间隔看,太规律了。我现在怀疑是 aws 有意限速,通过非常巧妙的少量丢包或乱序(图一中粗线下挂的小黑点),并控制 RTT,让 Linux TCP sender 的 cwnd 钳制在几十 KB,RTT 在 10ms,进而限制吞吐量在几千 KB/s。 我在 t3.micro 上用 FreeBSD 13 复现。观察到 AWS 先用对付 Linux 的办法:故意丢包乱序 + RTT=10ms,发现不灵之后,恼羞成怒,包也不丢了,直接卡脖子。总之就是不让你白嫖网速。对 Linux 是智斗,每秒钟丢你一两个包,RTT=10ms,让你自己cwnd小、速度上不去,你也不好说啥。对 FreeBSD 就上武力了。 ???对于测试的结果, 我这边确实不同,我读取到的RTT 60ms 明显要比大佬测试的时候的RTT 10ms 更高. 我把这个理解为 中国区AWS 与 Global的差异, 这个问题也许还能继续分析? 调整 rmem , wmem 的大小到 MTU * CWND = 9001 * 60 = 540600 ,这个数值x2 设置到发送和接收的窗口, 重新抓包, 理论上应该看不到快速重传了。并且拥塞窗口应该是稳定在 60 左右。 测试的过程中观察, 设置 rmem wmem 最终的值为 1000000, ss命令中的 CWND稳定在 57 , 抓包的结果中没有快速重传, RTT也比较稳定了, 不再有跳跃和突然增加到 100+ 的RTT, 速度还是被限制了, 这时候较小的是 RWND, 所以也是为什么 CWND 可以比较稳定不再变化的原因。 Topic 2 如何使用wireshark查看丢包率?如何查看实例在限速状态的 丢包率 和 重传率? 在客户端的抓包结果里面, 使用字段 tcp.stream eq 0 and tcp.analysis.fast_retransmission 调整到对应的 tcp stream, 然后在Conversion s窗口中统计的 Percent Filter 里面的百分比就是重传率, 丢包应该是 : tcp.analysis.lost_segment 或者就直接使用IO Graphs, 然后可以看到下面的图像,可以看到这个丢包比较小, 所以我在Y轴设置 100 的 Factor, 这样看起来清楚些。 如图: 基于这个抓包结果里面的基本上是乱序和快速重传,Server是发送数据的源头, 客户端没有收到认为这个是丢包。 那么感觉丢包率看Client的抓包结果应该就可以。 查看重传率 从Server这测的抓包结果来看。 Topic 3 RTT的变长是不是流控可以设计的?这个rtt确实无法区分到底是底层的流控带来的, 或者是设计故意拖长的,更新额外测试的结果: 将三个实例完全换成 c5.large, 后续没有RTT非常高的的问题了, 如图: 尝试处理掉CPU 的 IOwait, 也就是将这个文件缩小到 500MB ,之后nginx的数据都从内存取出, 发现RTT增加到了120ms, 维持了较长的时间之后还会回到60ms, 不知道这个原因是什么, 但是看起来RTT不稳定可能确实和os本身没什么关系。 试试其他规格的实例: 尝试在c5的实例上面直接使用tc卡住网桥设备的带宽, 来模拟链路中的网络设备? 观察rtt看看是否有任何的变化。 测试的方法使用docker-compose启动两个pod, 文件如下: --- version: "3.8" services: pod1: image: 111.dkr.ecr.cn-north-1.amazonaws.com.cn/haydenarchlinux:latest restart: always pod2: image: 111.dkr.ecr.cn-north-1.amazonaws.com.cn/haydenarchlinux:latest restart: always ...
将ArchLinux作为节点加入EKS UnmanagedNode
发表于2023-04-20|更新于2025-05-10|Kubernetes
添加一个自管理的节点添加这个自管理的节点是直接添加进入集群的, 并未使用EKS节点组的概念, 所以这个节点是可以被重启, 或者健康检查失败的, 并不具有任何的扩展或者弹性管理的能力。 创建集群,启动一个新的 EC2, 登录到已经启动的 EKS 优化 OS 内,准备复制一些脚本过来。 添加EC2的标签: kubernetes.io/cluster/clusterName owned 配置EC2的Instance Profile 控制台获取 Kubernetes APIServer的Endpoint URL 获取 apiserver b64 CA : cat ~/.kube/config 这个文件里面可以找到 ,或者是通过EKS的控制台上面, 找到 Base64 的 CA。 编辑 userdata, 或者 ssh 登录到ec2上面创建一个bash脚本用来调用 bootstrap.sh mkdir ~/eks; touch ~/eks/start.sh --- #!/bin/bash set -ex B64_CLUSTER_CA= API_SERVER_URL= K8S_CLUSTER_DNS_IP=10.100.0.10 /etc/eks/bootstrap.sh ${ClusterName} --b64-cluster-ca ${B64_CLUSTER_CA} --apiserver-endpoint ${API_SERVER_URL} 集群里面没有节点组 , 也不会创建aws-auth configmap 所以节点无法正常的加入集群, 需要手动创建。 apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: [CLUSTER_ROLE] username: system:node:{{EC2PrivateDNSName}} mapUsers: | [] kind: ConfigMap metadata: name: aws-auth namespace: kube-system 需要复制的文件sudo pacman -S containerd # 安装Containerd scp /etc/eks/bootstrap.sh root@54.222.253.235:/etc/eks/bootstrap.sh # 复制bootstrap scp /usr/bin/imds root@54.222.253.235:/usr/bin/imds # shell 脚本, 用来帮忙调用ec2 metadata 获取实例和VPC子网的信息 scp -pr /etc/eks/ root@54.222.253.235:/etc/eks/ # 直接复制了eks的相关脚本和配置模板 scp -pr /var/lib/kubelet/kubeconfig root@54.222.253.235:/var/lib/kubelet/kubeconfig # 复制kubeletconfig配置文件模板 scp -pr /etc/kubernetes/ root@54.222.253.235:/etc/kubernetes/ # 复制 kubernetes 的配置文件 scp -pr /etc/kubernetes/kubelet/ root@54.222.253.235:/etc/kubernetes/kubelet/ # 上面的命令没有递归复制, 所以需要指定 # 设置对应的内核参数, 如果不做kubelet 会报错提示 这些参数不符合要求。 kernel.panic = 10 kernel.panic_on_oops = 1 vm.overcommit_memory = 1 Bootstrap 脚本内容分析记录一下脚本自动配置的内容, 大概就是 获取变量, aws的服务地址, ec2 元数据地址, 替换模板中的变量生成Kubelet配置文件 和 Containerd 的配置文件(这个替换是一次性的, 也就是说, bootstrap只能变更模板中的变量一次, 第二次执行只会生成刷新一次集群的信息, 以及重启服务)。 读取bootstrap后面给出的参数,设置变量, 例如: ClusterName etc. 查看Kubelet的版本, 决定Runtime, containerd | dockerd, 判断条件是 kubelet 版本 大于 1.24++ kubelet --version ++ grep -Eo '[0-9]\.[0-9]+\.[0-9]+' + KUBELET_VERSION=1.24.9 --- + IS_124_OR_GREATER=true + DEFAULT_CONTAINER_RUNTIME=containerd 设置ECR以及Pause容器地址# 获取region以及aws service domain + AWS_DEFAULT_REGION=cn-north-1 + AWS_SERVICES_DOMAIN=amazonaws.com.cn # 调用脚本 /etc/eks/get-ecr-uri.sh cn-north-1 amazonaws.com.cn '' + ECR_URI=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn + PAUSE_CONTAINER_IMAGE=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause + PAUSE_CONTAINER=918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5 + CA_CERTIFICATE_DIRECTORY=/etc/kubernetes/pki + CA_CERTIFICATE_FILE_PATH=/etc/kubernetes/pki/ca.crt 创建证书目录:+ mkdir -p /etc/kubernetes/pki + sed -i s,MASTER_ENDPOINT,https://CE0253A94B6B14215AE3282580CFA5E3.yl4.cn-north-1.eks.amazonaws.com.cn,g /var/lib/kubelet/kubeconfig + sed -i s,AWS_REGION,cn-north-1,g /var/lib/kubelet/kubeconfig + sed -i s,CLUSTER_NAME,NewClusterForManualJoin,g /var/lib/kubelet/kubeconfig 获取 VPC CIDR# imds shell script help to get metadata. imds: /usr/bin/imds ++ imds latest/meta-data/local-ipv4 ++ imds latest/meta-data/network/interfaces/macs/02:66:06:2e:48:08/vpc-ipv4-cidr-blocks 创建kubelet 配置, 计算预留的资源 和 MaxPod 等等参数的数值。/etc/kubernetes/kubelet/kubelet-config.json + mkdir -p /etc/systemd/system/kubelet.service.d + sudo mkdir -p /etc/containerd + sudo mkdir -p /etc/cni/net.d + sudo mkdir -p /etc/systemd/system/containerd.service.d 创建containerd 配置文件+ printf '[Service]\nSlice=runtime.slice\n' + sudo tee /etc/systemd/system/containerd.service.d/00-runtime-slice.conf + sudo sed -i s,SANDBOX_IMAGE,918309763551.dkr.ecr.cn-north-1.amazonaws.com.cn/eks/pause:3.5,g /etc/eks/containerd/containerd-config.toml kubelet配置和启动。+ sudo cp -v /etc/eks/containerd/kubelet-containerd.service /etc/systemd/system/kubelet.service + sudo chown root:root /etc/systemd/system/kubelet.service + sudo containerd config dump + systemctl enable kubelet + systemctl start kubelet 制作 NodeTemplate AMI 如果使用已经加入过集群的实例直接制作AMI, 节点会无法加入, kubelet报错是APIserver拒绝这个节点的加入。 2023-04-19T15:10:13Z kubelet-eks.daemon[11577]: E0419 15:10:13.325154 11577 event.go:267] Server rejected event '&v1.Event{TypeMeta:v1.TypeMeta{Kind:"", APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"ip-10-0-1-249.cn-northwest-1.compute.internal.17575e9c08aefd8d", GenerateName:"", Namespace:"default", SelfLink:"", UID:"", ResourceVersion:"", Generation:0, CreationTimestamp:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), DeletionTimestamp:<nil>, DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string(nil), ZZZ_DeprecatedClusterName:"", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, InvolvedObject:v1.ObjectReference{Kind:"Node", Namespace:"", Name:"ip-10-0-1-249.cn-northwes ...
Linux OS 网络流量控制测试
发表于2023-04-14|更新于2025-05-10|Linux
内核参数的说明对于 TCP 来说,会遇到如下的几个参数。 如果我们需要查看一下当前 OS 内与 tcp 相关的 Kernel 参数, 命令如下: ]$ sysctl -a | egrep "rmem|wmem|tcp_mem|adv_win|moderate" 其中主要需要关注的是: net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304 这两个参数表示的是当前内核预留的 Socket Buffer, 单位是Bytes, 也是具体指 内存 的大小。具体的说明我找到 Kernel文档的说明如下: tcp_rmem - vector of 3 INTEGERs: min, default, max min: Minimal size of receive buffer used by TCP sockets. It is guaranteed to each TCP socket, even under moderate memory pressure. Default: 4K default: initial size of receive buffer used by TCP sockets. This value overrides net.core.rmem_default used by other protocols. Default: 87380 bytes. This value results in window of 65535 with default setting of tcp_adv_win_scale and tcp_app_win:0 and a bit less for default tcp_app_win. See below about these variables. max: maximal size of receive buffer allowed for automatically selected receiver buffers for TCP socket. This value does not override net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables automatic tuning of that socket's receive buffer size, in which case this value is ignored. Default: between 87380B and 6MB, depending on RAM size. tcp_wmem - vector of 3 INTEGERs: min, default, max min: Amount of memory reserved for send buffers for TCP sockets. Each TCP socket has rights to use it due to fact of its birth. Default: 4K default: initial size of send buffer used by TCP sockets. This value overrides net.core.wmem_default used by other protocols. It is usually lower than net.core.wmem_default. Default: 16K max: Maximal amount of memory allowed for automatically tuned send buffers for TCP sockets. This value does not override net.core.wmem_max. Calling setsockopt() with SO_SNDBUF disables automatic tuning of that socket's send buffer size, in which case this value is ignored. Default: between 64K and 4MB, depending on RAM size. 这文档中的说明,默认的三个值分别是: 最小, 默认, 最大。测试了一下, 如果只是需要实际调整的话, 调整那个最大值即可, 在高延迟的链路中, 调整默认值或者最大值就可以生效。 在测试的过程中, 将三个值都写成一致,控制变量。 对于TCP协议的接收与发送两方, 各自有自己的 RecvBuffer 和 SendBuffer, 发送方会考虑链路上面可以承载的数据量(带宽), 以及 对方可以承载的数据量(rmem)参数使用的内存用量。 实际上, 只是更新 max 的值, 并不会更新 Recvbuffer.如果想增大 receive buffer 的大小, 可以增加 tcp_rmem 的 default 的值大小. 测试环境两个 EC2 c5.2xlarge, 其中一个部署 Nginx , 并使用如下配置文件部分设置 , 发布一个 Fedora ISO, 大小大约 2G。另一个上面只是客户端, 使用的访问客户端是Curl。 http { server { autoindex on; autoindex_localtime on; } } } 这个配置文件中的其他部分就省略吧。 测试准备测试的过程其实涉及了四个部分的 延迟 问题: 发送方的应用程序性能。 发送方的发送缓冲区大小, SendBuffer 接收方的接收缓冲区大小, RecvBuffer 接收方的应用程序性能。 调整延迟和控制带宽 , 这两个部分控制的都是网络传输部分的性能,测试的过程中默认认为 发送 以及接收方的性能都完全没有问题。 基准两个机器的内核参数使用默认值, 先通过 tc 流量控制注入一些延迟, 查看并分析RTT对于传输速度的影响。 两个server之间默认的内核参数: 服务端参数 net.ipv4.tcp_rmem = 4096 131072 6291456 net.ipv4.tcp_wmem = 4096 16384 4194304 客户端参数 net.ipv4.tcp_wmem = 4096 131072 6291456 net.ipv4.tcp_rmem = 4096 16384 4194304 curl 的 测试命令 如下: ~]$ curl -o /dev/null -s -w "time_namelookup:%{time_namelookup}\ntime_connect: %{time_connect}\ntime_appconnect: %{time_appconnect}\ntime_redirect: %{time_redirect}\ntime_pretransfer: %{time_pretransfer}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" http://nginx.liarlee.site/Fedora-Workstation-Live-x86_64-38_Beta-1.3.iso 如果使用默认的参数, 那么2G的 ISO 文件可以快速的传完, 这是两个实例的基准表现, 这也是创建了一个TCP Connection 的较好的性能表现, EC2 之间的带宽 10Gbps。 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 172.31.48.133:80... 100 1967M 100 1967M 0 0 1116M 0 0:00:01 0:00:01 --:--:-- 1116M * Connection #0 to host nginx.liarlee.site left intact time_connect: 0.005461 time_starttransfer: 0.005797 time_total: 1.762040 总体看起来使用了 2s 不到的时间, 就传输完成了2G的文件。 仅控制带宽在添加了带宽 控制, 带宽控制在 1000Mbps, 带宽监控结果: Curl命令的结果: % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1967M 100 1967M 0 0 118M 0 0:00:16 0:00:16 --:--:-- 118M time_connect: 0.002070 time_starttransfer: 0.002304 time_total: 16.633562 在仅仅控制带宽的前提下, 由于延迟忽略不计, 所以传输的数据量可以使用全部的带宽,这个场景下面传输的速度取决于网络带宽的大小, 网络带宽越大, 传输的数据量和速度都会相应的增加。 控制带宽+延迟给服务端添加一个 50ms 的 延迟, 使用 tc 工具, 参考文档, 命令如下: tc qdisc del dev eth0 root tc qdisc add dev eth0 root handle 1:0 htb default 1 tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1000mbit tc qdisc add dev eth0 parent 1:1 handle 2:0 netem delay 50ms 测试的时候使用curl命令, 将结果直接输出到 /dev/null, 这个场景下, 客户端收写数据的速度非常快,这样的测试排除了大文件落硬盘速度慢的问题, 但是也让客户端收到这批数据之后立刻可以发送ack给服务端(Client - ACK——> Server), 告知服务端我这边的数据已经处理完了, 回收 RecvBuffer 空间. 在添加带宽控制和 50ms 延迟之后, 带宽使用: ping 命令 确认 rtt : root@arch ~# ping nginx.liarlee.site PING nginx.liarlee.site (172.31.48.133) 56(84) bytes of data. 64 bytes from i ...
删除所有非Running状态的Pod
发表于2023-03-23|更新于2025-05-10|Kubernetes
背景 如果所有的节点上面都有Taint, 然后这个没有Taint的节点磁盘满了, 会导致当前的节点上面留下许多状态不正常的Pod, 这些Pod大概率是停留在了Evicted状态, 或者是Completed, 甚至是 Unknown 。 这种状态的Pod Deployment默认的情况下不会自动回收, 所以需要人工操作一下。 Knowledge Source 处理方法记录一个命令来处理这个类型的Pod。 kubectl delete pod --field-selector="status.phase==Failed" 测试方法 集群内两个节点, 其中一个节点Taint kubectl taint nodes ip-172-31-60-181.cn-north-1.compute.internal app=grafana:NoSchedule 启动30个Grafana 登录到节点上面, 创建一个巨大的文件, 触发DiskPressure。 fallocate -l 72G ./large.file 等待节点的DiskPressure被识别, 然后触发驱逐。 删除文件, 取消DiskPressure状态, 等待 30 个新的Pod Ready。rm -rf ./large.file 使用命令清除所有不是Running状态的Pod。~$ kubectl delete pod --field-selector="status.phase==Failed" Over.
bpftrace 使用tracepoint 追踪 tcp 状态变化
发表于2023-03-19|更新于2025-05-10|Linux
入门教程大佬的博客, 入门教程: http://arthurchiao.art/blog/bpf-advanced-notes-1-zh/ 记录基础的bpftrace使用方法单行程序的使用方法 [root@localhost-live ~]# bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s %s\n", comm, str(args->filename));}' Tracepoint如何获取可用参数的解释[root@localhost-live sys_enter_execve]# pwd /sys/kernel/tracing/events/syscalls/sys_enter_execve [root@localhost-live sys_enter_execve]# grep -ri . format:name: sys_enter_execve format:ID: 742 format:format: format: field:unsigned short common_type; offset:0; size:2; signed:0; format: field:unsigned char common_flags; offset:2; size:1; signed:0; format: field:unsigned char common_preempt_count; offset:3; size:1; signed:0; format: field:int common_pid; offset:4; size:4; signed:1; format: field:int __syscall_nr; offset:8; size:4; signed:1; format: field:const char * filename; offset:16; size:8; signed:0; format: field:const char *const * argv; offset:24; size:8; signed:0; format: field:const char *const * envp; offset:32; size:8; signed:0; format:print fmt: "filename: 0x%08lx, argv: 0x%08lx, envp: 0x%08lx", ((unsigned long)(REC->filename)), ((unsigned long)(REC->argv)), ((unsigned long)(REC->envp)) trigger:# Available triggers: trigger:# traceon traceoff snapshot stacktrace enable_event disable_event enable_hist disable_hist hist filter:none id:742 enable:0 记录尝试追踪tcp状态变化的方法关于bpftrace追踪的总结, 追踪tcp状态的方法, 通过使用特定的tracepoint的来获取tcp状态的变化: ~$ bpftrace -e 'tracepoint:sock:inet_sock_set_state { printf("%s %d %d\n", comm, pid, args->newstate); }' ~$ bpftrace -e 'tracepoint:sock:inet_sock_set_state { printf("%s - %d -> %d - %d - %s\n",strftime("%H:%M:%S.%L", nsecs), args->oldstate, args->newstate, pid, comm); }' 关于返回值的说明: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/blob/main/include/net/tcp_states.h tcp_set_state 是一个内核函数,用于设置 TCP 套接字的状态。它有 12 个可能的返回值,分别对应 TCP 协议中定义的 12 种状态1。这些状态是: 1 TCP_ESTABLISHED:连接已建立2 TCP_SYN_SENT:主动打开连接,已发送 SYN 包3 TCP_SYN_RECV:被动打开连接,已收到 SYN 包4 TCP_FIN_WAIT1:主动关闭连接,已发送 FIN 包5 TCP_FIN_WAIT2:主动关闭连接,已收到对方的 ACK 包6 TCP_TIME_WAIT:主动关闭连接,等待一段时间以确保对方收到最后一个 ACK 包7 TCP_CLOSE:连接已关闭8 TCP_CLOSE_WAIT:被动关闭连接,已收到 FIN 包9 TCP_LAST_ACK:被动关闭连接,已发送最后一个 ACK 包10 TCP_LISTEN:监听状态,等待被动打开连接11 TCP_CLOSING:双方同时关闭连接,交换 FIN 和 ACK 包的过程中12 TCP_NEW_SYN_RECV:临时状态,用于处理 SYN 队列溢出的情况 追踪点理解起来还是比较简单的, 查看追踪点可用的参数,在这个部分可以看。 ~$ cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_sendmsg/format name: sys_enter_sendmsg ID: 1252 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:unsigned char common_preempt_lazy_count; offset:8; size:1; signed:0; field:int __syscall_nr; offset:12; size:4; signed:1; field:int fd; offset:16; size:8; signed:0; field:struct user_msghdr * msg; offset:24; size:8; signed:0; field:unsigned int flags; offset:32; size:8; signed:0; print fmt: "fd: 0x%08lx, msg: 0x%08lx, flags: 0x%08lx", ((unsigned long)(REC->fd)), ((unsigned long)(REC->msg)), ((unsigned long)(REC->flags)) 如果是使用 kprobe 的话, 不能使用 args, 需要使用确定的arg0 - argN, 这个部分还在摸索, 目前尝试用这个参数还是失败。 取到对应的得值, 但是print不出来。
诗词收集
发表于2023-01-09|更新于2025-05-10|Books
收集一些自己平时见到的诗句: Update 2018-12-24 邻人焉有许多鸡,乞丐何曾有二妻。当时尚有周天子,何事纷纷说魏齐。 算不尽芸芸众生微贱命,回头看五味杂陈奈何天。 何时杖策相随去,任性逍遥不学禅。 百无一用是情深,万般奈何为情困。 桃李春风一杯酒,江湖夜雨十年灯。 杀人放火金腰带,修桥补路无尸骸。 残雪凝辉冷画屏,落梅横笛已三更,更无人处月胧明。我是人间惆怅客,知君何事泪纵横,断肠声里忆平生。 纳兰性德《浣溪沙·残雪凝辉冷画屏》 曾经沧海难为水,除却巫山不是云。取次花丛懒回顾,半缘修道半缘君。 人生到处应何似,应似飞鸿踏雪泥。 山有木兮木有枝,心悦君兮君不知。 嫦娥应悔偷灵药,碧海青天夜夜心。 满堂花醉三千客,一剑霜寒十四州。 早岁读书无甚解,晚年省事有奇功。 车遥遥,马憧憧。君游东山东复东,安得奋飞逐西风。愿我如星君如月,夜夜流光相皎洁。月暂晦,星常明。留明待月复,三五共盈盈。 范成大《车遥遥篇》 一身诗意千寻瀑,万古流芳四月天。 未曾相逢先一笑,初会便已许平生。 三千年读史不过功名利禄,九万里悟道终归诗酒田园。 君埋泉下泥销骨,我寄人间雪满头。 伤心桥下春波绿,曾是惊鸿照影来。 醉后不知天在水,满船清梦压星河。 秋风吹尽旧庭柯,黄叶丹枫客里过。一点禅灯半轮月,今宵寒较昨宵多。 细雨生寒未有霜,庭前木叶半青黄。小春此去无多日,何处梅花一绽香。 岁久人无千日好,春深花有几时红。是非入耳君须忍,半作痴呆半作聋。 清风不识字,何故乱翻书。 三过平山堂下,半生弹指声中。十年不见老仙翁,壁上龙蛇飞动。欲吊文章太守,仍歌杨柳春风。休言万事转头空,未转头时皆梦。 山月不知心里事,水风空落眼前花。 未若锦囊收艳骨,一抔冷土掩风流。 莫言下岭便无难,赚得行人空喜欢。正入万山圈子里,一山放过一山拦。 有美一人兮婉如清扬,识曲别音兮令姿煌煌。绣袂捧琴兮登君子堂,如彼萱草兮使我忧忘。欲赠之以紫玉尺,白银珰,久不见之兮湘水茫茫。 生如逆旅,一苇以航。 Update 2023-01-09 回头万里,故人长绝。易水萧萧西风冷,满座衣冠似雪。《贺新郎·别茂嘉十二弟》辛弃疾 洛阳城里春光好,洛阳才子他乡老。《菩萨蛮·洛阳城里春光好》韦庄 伤心桥下春波绿,曾是惊鸿照影来。《沈园二首·其一》陆游 谁见幽人独往来,缥缈孤鸿影。《卜算子·黄州定慧院寓居作》苏轼 琵琶弦上说相思。当时明月在,曾照彩云归。《临江仙·梦后楼台高锁》晏几道 此后锦书休寄,画楼云雨无凭。《清平乐·留人不住》晏几道 美人自刎乌江岸,战火曾烧赤壁山,将军空老玉门关。 食肉何曾尽虎头,卅年书剑海天秋。文章幸未逢黄祖,襆被今犹窘马周。自是汝才难用世,岂真吾相不当侯。须知少日拏云志,曾许人间第一流。 清代吴庆坻《题三十计小象》 时人不识凌云木,直待凌云始道高。 总有千古,横有八荒,前途似海,来日方长。 鹏北海,风朝阳,又携书剑路茫茫。明年此日青云去,却笑人间举子忙。 Update 2023-03-01 派克直播间飞花令 不是逢人苦誉君,亦狂亦侠亦温文。照人胆似秦时月,送我情如岭上云。 一生一代一双人,争教两处销魂。相思相望不相亲,天为谁春? 也信美人终作土,不堪幽梦太匆匆。 银字笙调。心字香烧。料芳悰、乍整还凋。待将春恨,都付春潮。过窈娘堤,秋娘渡,泰娘桥。 中心藏之,何日忘之! Update 2023-03-05 派克直播间飞花令 钓鱼台,十年不上野鸥猜。白云来往青山在,对酒开怀。欠伊周济世才,犯刘阮贪杯戒,还李杜吟诗债。酸斋笑我,我笑酸斋。晚归来,西湖山上野猿哀。二十年多少风流怪,花落花开。望云霄拜将台。袖星斗安邦策,破烟月迷魂寨。酸斋笑我,我笑酸斋。 知君用心如日月,事夫誓拟同生死。还君明珠双泪垂,恨不相逢未嫁时。 千古风流八咏楼,江山留与后人愁。水通南国三千里,气压江城十四州。 问余何意栖碧山,笑而不答心自闲。桃花流水窅然去,别有天地非人间。 德也狂生耳。偶然间,缁尘京国,乌衣门第。有酒惟浇赵州土,谁会成生此意。不信道、竟逢知己。青眼高歌俱未老,向尊前、拭尽英雄泪。君不见,月如水。共君此夜须沉醉。且由他,蛾眉谣诼,古今同忌。身世悠悠何足问,冷笑置之而已。寻思起、从头翻悔。一日心期千劫在,后身缘、恐结他生里。然诺重,君须记。 纳兰性德《金缕曲·赠梁汾》 恨君不似江楼月,南北东西,南北东西,只有相随无别离。恨君却似江楼月,暂满还亏,暂满还亏,待得团圆是几时? 吕本中《采桑子·恨君不似江楼月》 自君之出矣,不复理残机。思君如满月,夜夜减清辉。 张九龄《赋得自君之出矣》 Update 2023-03-08 派克直播间飞花令, “江” 字飞花令 江东子弟今虽在,肯与君王卷土来? 王安石《叠题乌江亭》 江雨霏霏江草齐,六朝如梦鸟空啼。 韦庄《台城》 残灯无焰影幢幢,此夕闻君谪九江。垂死病中惊坐起,暗风吹雨入寒窗。元稹《闻乐天授江州司马》 少年听雨歌楼上,红烛昏罗帐。壮年听雨客舟中,江阔云低、断雁叫西风。而今听雨僧庐下,鬓已星星也。悲欢离合总无情,一任阶前、点滴到天明。 蒋捷《虞美人·听雨》 杀尽江南百万兵,腰间宝剑血犹腥!老僧不识英雄汉,只管哓哓问姓名。 朱元璋 《不惹庵示僧》 Update 2023-08-11 历史记录 缺月挂疏桐,漏断人初静。谁见幽人独往来,缥缈孤鸿影。惊起却回头,有恨无人省。拣尽寒枝不肯栖,寂寞沙洲冷。 ——《卜算子·黄州定会院寓居作》 Update 2025-04-05 扬子江头杨柳春,杨花愁杀渡江人。 数声风笛离亭晚,君向潇湘我向秦。 – 郑谷 《淮上与友人别》 从别后,忆相逢。几回魂梦与君同。今宵剩把银釭照,犹恐相逢是梦中。 – 晏几道 《鹧鸪天·彩袖殷勤捧玉钟》 燎沉香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳干宿雨,水面清圆,一一风荷举。故乡遥,何日去?家住吴门,久作长安旅。五月渔郎相忆否?小楫轻舟,梦入芙蓉浦。 – 周邦彦 《苏幕遮·燎沉香》 并刀如水,吴盐胜雪,纤手破新橙。锦幄初温,兽烟不断,相对坐调笙。低声问:向谁行宿?城上已三更。马滑霜浓,不如休去,直是少人行!– 周邦彦 《少年游·并刀如水》 梅雨霁,暑风和。高柳乱蝉多。小园台榭远池波。鱼戏动新荷。薄纱厨,轻羽扇。枕冷簟凉深院。此时情绪此时天。无事小神仙。– 周邦彦《鹤冲天·梅雨霁》 记得武陵相见日,六年往事堪惊。回头双鬓已星星。谁知江上酒,还与故人倾。铁马红旗寒日暮,使君犹寄边城。只愁飞诏下青冥。不应霜塞晚,横槊看诗成。 – 周紫芝《临江仙·送光州曾使君》
制作一个可用的malloc image
发表于2023-01-03|更新于2025-05-10|Linux
写一个melloc的C程序#include <stdio.h> #include <stdlib.h> #include <string.h> #include <signal.h> #include <unistd.h> #define SIGTERM_MSG "SIGTERM received.\n" void sig_term_handler(int signum, siginfo_t *info, void *ptr) { write(STDERR_FILENO, SIGTERM_MSG, sizeof(SIGTERM_MSG)); } void catch_sigterm() { static struct sigaction _sigact; memset(&_sigact, 0, sizeof(_sigact)); _sigact.sa_sigaction = sig_term_handler; _sigact.sa_flags = SA_SIGINFO; sigaction(SIGTERM, &_sigact, NULL); } int main(int argc, char *argv[]) { if ( argc != 2 ) { printf("ERROR ELEMENT COUNTS."); return 1; } // printf ("%ld\n", atol(argv[1])); int *p; long n = atol(argv[1]) * 1024 * 1024; // printf ("%ld\n", n); printf("Allocate Memory Size: %ld MB.\n", atol(argv[1])); // Allocate Memory. p = (int *)malloc(n); if (p != NULL) printf("SUCCESS."); else printf("FAILED."); memset(p, 0, n); catch_sigterm(); free(p); sleep(3000); return 0; } 写一个DockerfileFROM alpine RUN apk add build-base COPY mem.c . RUN gcc -o mem mem.c # or RUN gcc -static -o mem mem.c FROM alpine COPY --from=0 ./mem . ENTRYPOINT [ "/mem" ] 进行一个很新的测试Build Image. dive build -t liarlee-malloc:latest . OR docker build -t liarlee-malloc:latest . Docker RUN.docker run --name malloc --rm -dt liarlee-malloc:latest 200 # docker run --name malloc --rm -dt liarlee-malloc:latest [MemorySize(MB)] Kubernetes Deployment RUN.--- apiVersion: apps/v1 kind: Deployment metadata: name: liarlee-malloc spec: selector: matchLabels: app: malloc replicas: 1 template: metadata: labels: app: malloc spec: containers: - name: malloc image: liarlee-malloc:latest args: [ "200" ]
Nginx性能调整(不一定对
发表于2022-12-27|更新于2025-05-10|Linux
Nginx 性能优化看了不少的文档和说明, 尝试调整一下Nginx,看看与默认的设置性能表现能有多大的差距,顺便记录一下步骤,不记录的话自己会忘记的。 Sysctl 参数~]$ cat /etc/sysctl.d/99-hayden.cof net.ipv4.tcp_wmem = 8192 4194304 8388608 net.ipv4.tcp_rmem = 8192 4194304 8388608 net.core.somaxconn = 262144 net.core.default_qdisc=fq net.ipv4.tcp_congestion_control=bbr Nginx Config~]$ cat /etc/nginx/nginx.conf user nginx; worker_processes 1; worker_cpu_affinity 10; # error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 10240; } ...# 后面的都是默认值。 Systemd Nginx Service~]$ systemctl cat nginx # /usr/lib/systemd/system/nginx.service [Unit] Description=The nginx HTTP and reverse proxy server After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/run/nginx.pid # Nginx will fail to start if /run/nginx.pid already exists but has the wrong # SELinux context. This might happen when running `nginx -t` from the cmdline. # https://bugzilla.redhat.com/show_bug.cgi?id=1268621 ExecStartPre=/usr/bin/rm -f /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/usr/sbin/nginx -s reload KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=process PrivateTmp=true LimitAS=infinity LimitRSS=infinity LimitCORE=infinity LimitNOFILE=65536 LimitNPROC=65535 Nice=-20 [Install] WantedBy=multi-user.target CPU Isolate~]$ cat /etc/default/grub GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 nvme_core.io_timeout=4294967295 rd.emergency=poweroff rd.shell=0 isolcpus=1 nohz_full=1 rcu_nocbs=1" GRUB_TIMEOUT=0 GRUB_DISABLE_RECOVERY="true" GRUB_TERMINAL="ec2-console" GRUB_X86_USE_32BIT="true" 调整中断~]$ cat /proc/interrupts CPU0 CPU1 27: 0 845 PCI-MSI 81920-edge ena-mgmnt@pci:0000:00:05.0 28: 1455005 0 PCI-MSI 81921-edge eth0-Tx-Rx-0 29: 0 1870959 PCI-MSI 81922-edge eth0-Tx-Rx-1 LOC: 119785 15755 Local timer interrupts ~]$ echo 0 > /proc/irq/29/smp_affinity_list ~]$ echo 0 > /proc/irq/28/smp_affinity_list ~]$ echo 0 > /proc/irq/27/smp_affinity_list 关闭 Irqbalance~]$ sudo systemctl stop irqbalance.service ~]$ sudo systemctl disable irqbalance.service Removed symlink /etc/systemd/system/multi-user.target.wants/irqbalance.service. 测试这些都做完之后,启动一个新的实例,安装nginx之后不做任何的动作, 使用ab命令测试默认页 index.html。 对比 调整后的实例结果如下使用命令: ab -c 3000 -n 50000 http://172.31.37.166:80/index.html 第一次Document Path: /index.html Document Length: 732 bytes Concurrency Level: 3000 Time taken for tests: 2.225 seconds Complete requests: 50000 Failed requests: 0 Total transferred: 48250000 bytes HTML transferred: 36600000 bytes Requests per second: 22474.64 [#/sec] (mean) Time per request: 133.484 [ms] (mean) Time per request: 0.044 [ms] (mean, across all concurrent requests) Transfer rate: 21179.71 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 67 139.7 47 1124 Processing: 25 63 16.1 61 274 Waiting: 0 47 13.7 46 254 Total: 57 130 143.2 106 1191 Percentage of the requests served within a certain time (ms) 50% 106 66% 125 75% 131 80% 135 90% 142 95% 149 98% 165 99% 1173 100% 1191 (longest request) 第二次Document Path: /index.html Document Length: 732 bytes Concurrency Level: 3000 Time taken for tests: 2.232 seconds Complete requests: 50000 Failed requests: 0 Total transferred: 48250000 bytes HTML transferred: 36600000 bytes Requests per second: 22397.25 [#/sec] (mean) Time per request: 133.945 [ms] (mean) Time per request: 0.045 [ms] (mean, across all concurrent requests) Transfer rate: 21106.78 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 67 141.3 47 1092 Processing: 22 63 15.8 60 106 Waiting: 0 47 13.5 46 84 Total: 60 130 143.5 108 1175 Percentage of the requests served within a certain time (ms) 50% 108 66% 122 75% 131 80% 134 90% 141 95% 149 98% 165 99% 1150 100% 1175 (longest request) 第三次Document Path: /index.html Document Length: 732 bytes Concurrency Level: 3000 Time taken for tests: 2.220 seconds Complete requests: 50000 Failed requests: 0 Total transferred: 48250000 bytes HTML transferred: 36600000 bytes Requests per second: 22526.08 [#/sec] (mean) Time per request: 133.179 [ms] (mean) Time per request: 0.044 [ms] (mean, across all concurrent requests) Transfer rate: 21228.19 [Kbytes/sec] received Connection ...
Docker/Containerd/Harbor 配置代理
发表于2022-12-20|更新于2025-05-10|Docker
记录一下 Docker Daemon / Containerd 配置代理的步骤,尽管能用的时候不太多。 Update - 2023-07-10 Add Harbor. Docker创建文件]$ mkdir -pv /etc/systemd/system/docker.service.d ]$ touch /etc/systemd/system/docker.service.d/proxy.conf 写入内容[Service] Environment="HTTP_PROXY=socks5://<-->:<-->/" Environment="HTTPS_PROXY=socks5://<-->:<-->/" Environment="NO_PROXY=localhost,127.0.0.1" 重启DockerDaemon]$ sudo systemctl daemon-reload && sudo systemctl restart docker Containerd创建环境变量文件]$ mkdir -pv /etc/systemd/system/containerd.service.d ]$ touch /etc/systemd/system/containerd.service.d/proxy.conf 写入内容[Service] Environment="HTTP_PROXY=socks5://<-->:<-->/" Environment="HTTPS_PROXY=socks5://<-->:<-->/" Environment="NO_PROXY=localhost,127.0.0.1" 重启 Containerd]$ sudo systemctl daemon-reload && sudo systemctl restart docker Harbor 仓库加代理另一个方法是直接给harbor仓库添加代理, 让Harbor来进行代理访问 ,帮忙pull镜像, 集群直接指向这个仓库即可。 harbor我是直接使用docker-compose 的方式部署的, 这样简单一些。 我的软件安装目录是在: /opt/harbor 找到harbor 的配置文件: /opt/harbor/harbor.yml 配置文件部分如下: 189 # Global proxy 190 # Config http proxy for components, e.g. http://my.proxy.com:3128 191 # Components doesn't need to connect to each others via http proxy. 192 # Remove component from `components` array if want disable proxy 193 # for it. If you want use proxy for replication, MUST enable proxy 194 # for core and jobservice, and set `http_proxy` and `https_proxy`. 195 # Add domain to the `no_proxy` field, when you want disable proxy 196 # for some special registry. 197 proxy: 198 http_proxy: socks5://ip:port 199 https_proxy: socks5://ip:port 200 no_proxy: 201 components: 202 - core 203 - jobservice 204 - trivy 启动服务之后进入容器进行确认: core]$ dc exec -it core bash harbor [ /harbor ]$ env | grep -i proxy PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub,harbor,azure-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr NO_PROXY=redis,chartmuseum,portal,db,.internal,.local,127.0.0.1,localhost,core,trivy-adapter,nginx,postgresql,registryctl,log,jobservice,registry,notary-server,notary-signer,exporter HTTPS_PROXY=socks5://ip:port HTTP_PROXY=socks5://ip:port 环境变量已经生效了, 然后直接在控制台创建项目, 创建新的仓库缓存代理。 我创建的仓库如下,除了列出的其他留空: 提供者 目标名 目标URL Quay registry.k8s.io https://registry.k8s.io GtihubGHCR ghcr.io https://ghcr.io Quay k8s.gcr.io (Archived) https://k8s.gcr.io Quay gcr.io https://gcr.io Quay quay.io https://quay.io Docker Hub docker.io https://hub.docker.com DockerRegistry public.ecr.aws https://public.ecr.aws 所有仓库的健康检查是通过的, 然后去创建项目, 就行了。 创建完成项目之后, 就可以通过当前这个仓库的项目地址来pull 镜像了。 docker pull reg.liarlee.site/docker.io/library/nginx:latest docker pull reg.liarlee.site/registry.k8s.io/metrics-server/metrics-server@sha256:1ab8d2722ce57979eb05ec0594cb9173e07ace16a253c747bb94c31b138a07dc docker pull reg.liarlee.site/public.ecr.aws/amazonlinux/amazonlinux:minimal docker pull reg.liarlee.site/quay.io/prometheus/prometheus docker pull reg.liarlee.site/quay.io/argoproj/argocd docker pull reg.liarlee.site/ghcr.io/dexidp/dex
1…678…16
avatar
Liarlee
Archlinux User, Support Engineer
文章
155
标签
73
分类
16
Follow Me
公告
都道无人愁似我,今夜雪,有梅花,似我愁。
最新文章
CheatSheet_Kubernetes2333-12-08
CheatSheet_Linux2333-12-08
CheatSheet_awscli2333-12-08
CheatSheet_Databases2333-12-08
Fortio 笔记2025-05-09
TrueNAS Core 自动更新UI证书2024-11-15
分类
  • AWS2
  • Application5
  • Books5
  • Database8
  • Docker6
  • EKS5
  • ESXi1
  • ElasticSearch2
标签
TrueNasCore btrfs Repo Android ElasticSearch Git Redis KVM LogAgent Headscale MongoDB Cilium Orthanc Prometheus Ranger VPC FileSystem JAVA Network Steam NAS RPM Memory Ceph Fedora Filesystem Nvidia GRUB2 Strace AWS CPU Firefox 诗 EBS Ansible Python RIME SElinux Database Hexo
归档
  • 十二月 23334
  • 五月 20251
  • 十一月 20241
  • 九月 20242
  • 八月 20241
  • 七月 20243
  • 六月 20242
  • 五月 20244
网站资讯
文章数目 :
155
本站总字数 :
183k
本站访客数 :
本站总访问量 :
最后更新时间 :
©2020 - 2025 By Liarlee
框架 Hexo|主题 Butterfly
搜索
数据库加载中