zz:linux之网络性能调优(基于/proc/sys/net/ipv4/ 参数配置)

本文介绍了LINUX网络性能调谐的方法,包括服务方式选择、线程数量调整、内核参数配置等内容。并探讨了IPv4到IPv6的过渡机制。

在《调谐LINUX网络性能之调试工具篇》和《调谐LINUX网络性能之网络配置文件详解》两篇文章中,我们介绍了route、netstat、tcpdump三种网络调谐测试工具的使用方法及其可实现的功能和网络配置文件的内容,本文我们将从实战的角度介绍网络性能调谐的方法。

下面,我们先来介绍网络性能调谐的第一种方法:服务方式选择。

服务方式选择


网络服务器由于要同时为多个客户提供服务,就必须使用某种方式来支持这种多任务的服务方式。一般情况下可以有三种方式来选择,多进程方式、多线程方式及异步方式。其中,多进程方式中服务器对一个客户要使用一个进程来提供服务,由于在操作系统中,生成一个进程需要进程内存复制等额外的开销,这样在客户较多时的性能就会降低。为了克服这种生成进程的额外开销,可以使用多线程方式或异步方式。在多线程方式中,使用进程中的多个线程提供服务,由于线程的开销较小,性能就会提高。事实上,不需要任何额外开销的方式还是异步方式,它使用非阻塞的方式与每个客户通信,服务器使用一个进程进行轮询就行了。异步方式下,多个任务之间的调度是由服务器程序自身来完成的,而且一旦一个地方出现问题则整个服务器就会出现问题,不在讨论的范围内。增大系统线程的数量:限制线程的数量的因素很多,主要有进程数量的限制,内存大小的限制,mutex/semaphore/shm/ipc的限制;一般情况下先增大进程最大数,再扩充内存,在增大线程最大数,而增大线程最大数的方法很简单,只需改变glibc中两处即可:线程最大数和线程堆栈区的大小;线程最大数的增加是以进程的异步I/O性能下为代价;所以需要加以平衡。

络配置文件中有用的内容


1. 对于数据库而言,增大共享内存段和信号量的多少,对数据传输效率的提高起到很重要的作用;

方法:只需编辑文件linux/include/linux/sem.h和linux/include/asm-i386/shmparam.h即可。

2. 先增大进程最大数,再扩充内存,再增大线程最大数,而增大线程最大数的方法很简单,只需改变glibc中两处即可:线程最大数和线程堆栈区的大小;

3. 把"/etc/inittab"文件中的一行注释掉可以禁止用Control-Alt-Delete关闭计算机。如果服务器不是放在一个安全的地方,这非常重要。

编辑inittab文件(vi /etc/inittab)把这一行:

ca::ctrlaltdel:/sbin/shutdown -t3 -r now



改为:

#ca::ctrlaltdel:/sbin/shutdown -t3 -r now



用下面的命令使改变生效:

[root@deep]# /sbin/init q



4. /etc/host.conf 文件指定如何解析主机名。Linux通过解析器库来获得主机名对应的IP地址。下面是一个"/etc/host.conf"的示例:

order bind,hosts :指定主机名查询顺序,这里规定先使用DNS来解析域名,然后再查询"/etc/hosts"文件(也可以相反)。

可以在该文件后加上以下两句:

multi on:指定的主机可以有多个地址,拥有多个IP地址的主机一般称为多穴主机。

ospoof on:指不允许对该服务器进行IP地址欺骗,以提高服务器的安全性。IP欺骗是一种攻击系统安全的手段,通过把IP地址伪装成别的计算机,来取得其它计算机的信任。

可调谐的Linux内核网络参数


ICMP相关内核配置参数

概述:通常我们使用icmp包来探测目的主机上的其它协议(如tcp和udp)是否可用。比如包含"destination unreachable"信息的icmp包就是最常见的icmp包。

(1) icmp_destunreach_rate:设置内容为"Destination Unreachable"icmp包的响应速率。设置值应为整数。

应用实例: 假设有A、B两部主机,首先我们在主机A上执行以下ipchains语句:

ipchains -A input -p icmp -j REJECT



这里的REJECT和DENY不同,DENY会丢掉符合条件的包如同没有接收到该包一样,而REJECT会在丢掉该包的同时给请求主机发回一个"Destination Unreachable"的icmp。

然后在主机B上ping主机A,这时候我们会发现"Destination Unreachable"icmp包的响应速度是很及时的。接着我们在主机A上执行:

echo "1000" > /proc/sys/net/ipv4/icmp_destunreach_rate



也即每10秒钟响应一个"Destination Unreachable"的icmp包。

这时候再从主机B上ping主机A就会发现"Destination Unreachable"icmp包的响应速度已经明显变慢,我很好奇的测试了一下,发现刚好是每10秒响应一次。

(2)icmp_echo_ignore_broadcasts:设置是否响应icmp echo请求广播,设置值应为布尔值,0表示响应icmp echo请求广播,1表示忽略。

注意:windows系统是不响应icmp echo请求广播的。

应用实例:

在我的RedHat6.x和RedHat7上该值缺省为0,这样当有个用户ping我的服务器所在的网段的网络地址时,所有的linux服务器就会响应,从而也能让让该用户得到我的服务器的ip地址,可以执行

echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts



来关闭该功能。从而防止icmp风暴,防止网络阻塞。

(3)icmp_echoreply_rate:设置系统响应icmp echo请求的icmp包的响应速度,设置值为整数。

应用实例:

假设有A、B两部主机,首先我们在主机B上ping主机A,可以看到响应很正常,然后在主机A上执行

echo "1000" > /proc/sys/net/ipv4/icmp_echoreply_rate



也即每10秒钟响应一个icmp echo请求包。然后再ping主机A就可以看到响应速度已经变成10秒一次。

最好合理的调整该参数的值来防止icmp风暴。

(4)icmp_echo_ignore_all:设置系统是否忽略所有的icmp echo请求,如果设置了一个非0值,系统将忽略所有的icmp echo请求。其实这是icmp_echoreply_rate的一种极端情况。参数值为布尔值,1:表示忽略,0:表示响应。

(5)icmp_paramprob_rate:当系统接收到数据报的损坏的ip或tcp头时,就会向源发出一个包含有该错误信息的icmp包。这个参数就是用来设置向源发送这种icmp包的速度。当然,在通常情况下ip或tcp头出错是很少见的。参数值为整数。

(6) icmp_timeexceed_rate:数据报在网络上传输时,其生存时间(time to live)字段会不断减少,当生存时间为0时,正在处理该数据报的路由器就会丢弃该数据报,同时给源主机发送一个"time to live exceeded"的icmp包。该参数就是用来设置这种icmp包的发送的速度。当然,这通常用于充当路由器的linux主机。

IP相关内核配置参数

linux内核网络参数中关于ip的配置参数通常是用来定义或调整ip包的一些特定的参数,除此之外还定义了系统的一些网络特性。

(1) ip_default_ttl:设置从本机发出的ip包的生存时间,参数值为整数,范围为0~128,缺省值为64。在windows系统中,ip包的生存时间通常为128。如果你的系统经常得到"Time to live exceeded"的icmp回应,可以适当增大该参数的值,但是也不能过大,因为如果你的路由坏路的话,就会增加系统报错的时间。

(2) ip_dynaddr:该参数通常用于使用拨号连接的情况,可以使系统能够立即改变ip包的源地址为该ip地址,同时中断原有的tcp对话而用新地址重新发出一个syn请求包,开始新的tcp对话。在使用ip欺骗时,该参数可以立即改变伪装地址为新的ip地址。该参数的参数值可以是:

1:启用该功能 
2:使用冗余模式启用该功能 
0:禁止该功能



应用实例:在使用ipchains配置ip欺骗带动局域网共享一个ppp连接上网时,有时会出现刚开时连接一个站点连不通,再次刷新又可以连接的情况,这时候就可以设置该参数的值为1,从而立即改变伪装地址为新的ip地址,就可以解决这类问题。命令为:

echo "1" > /proc/sys/net/ipv4/ip_dynaddr




(3)ip_forward:可以通过该参数来启用包转发功能,从而使系统充当路由器。参数值为1时启用ip转发,为0时禁止ip转发。注意,我们可以在单网卡或双网卡的主机上实现ip转发。

应用实例:

假设我们使用一部装有双网卡的linux主机充当防火墙,这时候我们就必须执行以下命令来打开ip转发功能:

echo "1" > /proc/sys/net/ipv4/ip_forward



(4) ip_local_port_range:设置当本地系统向外发起tcp或udp连接请求时使用的端口范围。设置值为两个整数,缺省为"1024 4999"。

应用实例:

echo "1450 6000" > /proc/sys/net/ipv4/ip_local_port_range



tcp相关内核配置参数

通过tcp配置参数可以控制tcp会话过程中的各个方面。

(1) tcp_fin_timeout:在一个tcp会话过程中,在会话结束时,A首先向B发送一个fin包,在获得B的ack确认包后,A就进入FIN WAIT2状态等待B的fin包然后给B发ack确认包。这个参数就是用来设置A进入FIN WAIT2状态等待对方fin包的超时时间。如果时间到了仍未收到对方的fin包就主动释放该会话。参数值为整数,单位为秒,缺省为180秒。

(2) tcp_syn_retires:设置开始建立一个tcp会话时,重试发送syn连接请求包的次数。 参数值为小于255的整数,缺省值为10。假如你的连接速度很快,可以考虑降低该值来提高系统响应时间,即便对连接速度很慢的用户,缺省值的设定也足够大了。

(3) tcp_window_scaling:设置tcp/ip会话的滑动窗口大小是否可变。参数值为布尔值,为1时表示可变,为0时表示不可变。Tcp/ip 通常使用的窗口最大可达到65535字节,对于高速网络,该值可能太小,这时候如果启用了该功能,可以使tcp/ip滑动窗口大小增大数个数量级,从而提高数据传输的能力。

针对每一网络接口的内核网络参数

通过针对每一网络接口的内核网络参数,你可以为诸如eth0、eth1等具体的网络接口指定响应的内核网络参数。注意:/proc/sys/net/ipv4/conf/all/下的参数将应用于所有的网络接口。

(1) accept_redirects:该参数位于/proc/sys/net/ipv4/conf/DEV/accept_redirects(DEV表示具体的网络接口),如果你的主机所在的网段中有两个路由器,你将其中一个设置成了缺省网关,但是该网关在收到你的ip包时发现该ip包必须经过另外一个路由器,这时这个路由器就会给你发一个所谓的"重定向"icmp包,告诉将ip包转发到另外一个路由器。参数值为布尔值,1表示接收这类重定向icmp 信息,0表示忽略。在充当路由器的linux主机上缺省值为0,在一般的linux主机上缺省值为1。建议将其改为0,或者使用"安全重定向"(见下文)以消除安全性隐患。

(2) log_martians:将包含非法地址信息的ip包记录到内核日志。参数值为布尔值。

应用实例:

上面我们讲过rp_filter反向路径过滤参数,同时我们可以执行下面的语句

echo "1" > /proc/sys/net/ipv4/conf/all/log_martians



然后就可以将进行ip假冒的ip包记录到/var/log/messages。

(3) forwarding:启用特定网络接口的ip转发功能。参数值为布尔值,1表示进行记录。

应用实例:

echo "1" > /proc/sys/net/ipv4/conf/eth0/forwarding



(4) accept_source_route:是否接受含有源路由信息的ip包。参数值为布尔值,1表示接受,0表示不接受。在充当网关的linux主机上缺省值为1,在一般的linux主机上缺省值为0。从安全性角度出发,建议你关闭该功能。

(5) secure_redirects:前面我们已经提到过"安全重定向"的概念,其实所谓的"安全重定向"就是只接受来自网关的"重定向"icmp包。该参数就是用来设置"安全重定向"功能的。参数值为布尔值,1表示启用,0表示禁止,缺省值为启用。

(6) proxy_arp:设置是否对网络上的arp包进行中继。参数值为布尔值,1表示中继,0表示忽略,缺省值为0。该参数通常只对充当路由器的linux主机有用。

改变有关系统缺省参数限制



1. _SHM_ID_BITS:在/usr/src/linux/include/asm/shmparam.h文件中定义了该值;

作用:定义共享内存段表识的数量;其缺省值为7,变化范围:1-128;

调谐:可将该值增大到9,需重新编译内核;

2. MSGMNI:/proc/sys/kernel/msgmni文件中定义了该值;

作用:该值定义了消息队列的最大长度;要使db2(7.1版)正常运行,其最小值为128;

对于高负荷的DB2服务器,可将该值调整为 >= 1024;

调谐:对于2.4.6版本的内核,其缺省值为16;可用以下三中方法改变该值

(1) bash# sysctl -w kernel.msgmni=128

(2) bash# sysctl -w kernel.msgmni=128

(3) 如果要在系统启动时改变该值,可在/etc/sysctl.conf文件中加入以下几句:

# Sets maximum number of message queues to 128
# Set this to 1024 or higher on production systems
kernel.msgmni = 128



(用ipcs -l 命令来查看当前ipc 参数的各种设置)

3. NR_TASKS:/usr/src/linux/include/linux/tasks.h文件中定义了该

MAX_TASKS_PER_USER被定义为NR_TASKS/2;linux 将DB2的每个实例看作用户,每个连结一般都使用一个进程,而每个实例的最大连结数被限制为NR_TASKS/2;尽管2.4的内核对该值无限制,但有linux该缺省值仍为512;

调谐:>= 1024, 重新编译内核;

4. SEMMNI:/usr/src/linux/include/linux/sem.h 文件中定义了该值;

作用:该值定义了linux所能支持的最大信号量表识;

调谐:其缺省值为128,增大到1024;

从IPV4过渡到IPV6



尽管IPv6比IPv4具有明显的先进性,要想在短时间内将Internet和各个企业网络中的所有系统全部从IPv4升级到 IPv6是不可能的。为此,做为IPv6研究工作的一个部分,IETF制定了推动IPv4向IPv6过渡的方案,其中包括三个机制:兼容IPv4的 IPv6地址、双IP协议栈和基于IPv4通道的IPv6。

兼容IPv4的IPv6地址是一种特殊的IPv6单点广播地址,一个 IPv6节点与一个IPv4节点可以使用这种地址在IPv4网络中通信。这种地址是由96个0位加上32位IPv4地址组成的,例如,假设某节点的 IPv4地址是192.56.1.1,那么兼容IPv4的IPv6地址就是:

0: 0:0:0:0:0:C038:101。



双 IP协议栈是在一个系统(如一个主机或一个路由器)中同时使用IPv4和IPv6两个协议栈。这类系统既拥有IPv4地址,也拥有IPv6地址,因而可以收发IPv4和IPv6两种IP数据报。也就是用两套,需要使用IPv4的时候就使用IPv4,需要使用IPv6的时候就使用IPv6。

与双IP协议栈相比,基于IPv4通道的IPv6是一种更为复杂的技术,它是将整个IPv6数据报封装在IPv4数据报中,由此实现在当前的IPv4网络(如Internet)中IPv6节点与IPv4节点之间的IP通信。基于IPv4通道的IPv6实现过程分为三个步骤:封装、解封和通道管理。封装,是指由通道起始点创建一个IPv4包头,将IPv6数据报装入一个新的IPv4数据报中。解封,是指由通道终结点移去IPv4包头,还原原始的IPv6数据报。通道管理,是指由通道起始点维护通道的配置信息。IPv4通道有四种方案:路由器对路由器、主机对路由器、主机对主机、路由器对主机。

当进行通信的两个主机都有兼容IPv4的IPv6地址时,数据发送方主机将建立一个主机对主机通道。通道起始点(数据发送方主机)确定数据接收方主机就是通道终结点,并自动从其兼容IPv4的IPv6地址中抽取后32个地址位以确定通道终结点的IPv4地址,这种类型的通道被称为自动通道(automated tunneling)。

双IP协议栈和基于IPv4通道的IPv6网络使IPv4网络能够以可控的速度向 IPv6迁移。在开始向IPv6过渡之前,必须设置一个同时支持IPv4和IPv6的新的DNS服务器。有关设置或关于IPv6更多的详细内容可访问 IPv6相关网站。我们在这里仅为在Linux下使用IPV6提供一种简单的理论叙述。

nvidia@nvidia-desktop:~$ sudo systemctl status docker cri-dockerd # 确保cri-dockerd已安装(Kubernetes 1.24+必需) if ! command -v cri-dockerd &> /dev/null; then Unit cri-dockerd.service could not be found. ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 14:21:01 CST; 10s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 307670 (dockerd) Tasks: 12 Memory: 32.0M CGroup: /system.slice/docker.service └─307670 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.905384514+08:00" level=info msg="Starting up" 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.907450939+08:00" level=info msg="detected 127.0.0.53 nameserver, assuming system> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.933499466+08:00" level=info msg="[graphdriver] trying configured driver: overlay> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.950999544+08:00" level=info msg="Loading containers: start." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.068395372+08:00" level=info msg="Default bridge (docker0) is assigned with an IP> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.119938208+08:00" level=info msg="Loading containers: done." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136753856+08:00" level=info msg="Docker daemon" commit="26.1.3-0ubuntu1~20.04.1"> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136876237+08:00" level=info msg="Daemon has completed initialization" 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.175939143+08:00" level=info msg="API listen on /run/docker.sock" 12月 08 14:21:01 nvidia-desktop systemd[1]: Started Docker Application Container Engine. ...skipping... Unit cri-dockerd.service could not be found. ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 14:21:01 CST; 10s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 307670 (dockerd) Tasks: 12 Memory: 32.0M CGroup: /system.slice/docker.service └─307670 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.905384514+08:00" level=info msg="Starting up" 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.907450939+08:00" level=info msg="detected 127.0.0.53 nameserver, assuming system> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.933499466+08:00" level=info msg="[graphdriver] trying configured driver: overlay> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.950999544+08:00" level=info msg="Loading containers: start." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.068395372+08:00" level=info msg="Default bridge (docker0) is assigned with an IP> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.119938208+08:00" level=info msg="Loading containers: done." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136753856+08:00" level=info msg="Docker daemon" commit="26.1.3-0ubuntu1~20.04.1"> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136876237+08:00" level=info msg="Daemon has completed initialization" 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.175939143+08:00" level=info msg="API listen on /run/docker.sock" 12月 08 14:21:01 nvidia-desktop systemd[1]: Started Docker Application Container Engine. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ...skipping... ~ Unit cri-dockerd.service could not be found. ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 14:21:01 CST; 10s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 307670 (dockerd) Tasks: 12 Memory: 32.0M CGroup: /system.slice/docker.service └─307670 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.905384514+08:00" level=info msg="Starting up" 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.907450939+08:00" level=info msg="detected 127.0.0.53 nameserver, assuming system> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.933499466+08:00" level=info msg="[graphdriver] trying configured driver: overlay> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.950999544+08:00" level=info msg="Loading containers: start." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.068395372+08:00" level=info msg="Default bridge (docker0) is assigned with an IP> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.119938208+08:00" level=info msg="Loading containers: done." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136753856+08:00" level=info msg="Docker daemon" commit="26.1.3-0ubuntu1~20.04.1"> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136876237+08:00" level=info msg="Daemon has completed initialization" 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.175939143+08:00" level=info msg="API listen on /run/docker.sock" 12月 08 14:21:01 nvidia-desktop systemd[1]: Started Docker Application Container Engine. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ...skipping... ~ Unit cri-dockerd.service could not be found. ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 14:21:01 CST; 10s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 307670 (dockerd) Tasks: 12 Memory: 32.0M CGroup: /system.slice/docker.service └─307670 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.905384514+08:00" level=info msg="Starting up" 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.907450939+08:00" level=info msg="detected 127.0.0.53 nameserver, assuming system> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.933499466+08:00" level=info msg="[graphdriver] trying configured driver: overlay> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.950999544+08:00" level=info msg="Loading containers: start." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.068395372+08:00" level=info msg="Default bridge (docker0) is assigned with an IP> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.119938208+08:00" level=info msg="Loading containers: done." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136753856+08:00" level=info msg="Docker daemon" commit="26.1.3-0ubuntu1~20.04.1"> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136876237+08:00" level=info msg="Daemon has completed initialization" 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.175939143+08:00" level=info msg="API listen on /run/docker.sock" 12月 08 14:21:01 nvidia-desktop systemd[1]: Started Docker Application Container Engine. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ! command -v cri-dockerd &> /dev/null; then wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd_0.3.4.3-0.ubuntu-jammy_amd64.deb sudo dpkg -i cri-dockerd_0.3.4.3-0.ubuntu-jammy_amd64.deb fi # 重启容器运行时 sudo systemctl restart docker cri-dockerd /bin/bash: -c: line 0: syntax error near unexpected token `then' /bin/bash: -c: line 0: ` command -v cri-dockerd &> /dev/null; then' !done (press RETURN) ...skipping... ~ Unit cri-dockerd.service could not be found. ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2025-12-08 14:21:01 CST; 10s ago TriggeredBy: ● docker.socket Docs: https://docs.docker.com Main PID: 307670 (dockerd) Tasks: 12 Memory: 32.0M CGroup: /system.slice/docker.service └─307670 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.905384514+08:00" level=info msg="Starting up" 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.907450939+08:00" level=info msg="detected 127.0.0.53 nameserver, assuming system> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.933499466+08:00" level=info msg="[graphdriver] trying configured driver: overlay> 12月 08 14:21:00 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:00.950999544+08:00" level=info msg="Loading containers: start." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.068395372+08:00" level=info msg="Default bridge (docker0) is assigned with an IP> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.119938208+08:00" level=info msg="Loading containers: done." 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136753856+08:00" level=info msg="Docker daemon" commit="26.1.3-0ubuntu1~20.04.1"> 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.136876237+08:00" level=info msg="Daemon has completed initialization" 12月 08 14:21:01 nvidia-desktop dockerd[307670]: time="2025-12-08T14:21:01.175939143+08:00" level=info msg="API listen on /run/docker.sock" 12月 08 14:21:01 nvidia-desktop systemd[1]: Started Docker Application Container Engine. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ...skipping... SUMMARY OF LESS COMMANDS Commands marked with * may be preceded by a number, N. Notes in parentheses indicate the behavior if N is given. A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. h H Display this help. q :q Q :Q ZZ Exit. --------------------------------------------------------------------------- MOVING e ^E j ^N CR * Forward one line (or N lines). y ^Y k ^K ^P * Backward one line (or N lines). f ^F ^V SPACE * Forward one window (or N lines). b ^B ESC-v * Backward one window (or N lines). z * Forward one window (and set window to N). w * Backward one window (and set window to N). ESC-SPACE * Forward one window, but don't stop at end-of-file. d ^D * Forward one half-window (and set half-window to N). u ^U * Backward one half-window (and set half-window to N). ESC-) RightArrow * Right one half screen width (or N positions). ESC-( LeftArrow * Left one half screen width (or N positions). ESC-} ^RightArrow Right to last column displayed. ESC-{ ^LeftArrow Left to first column. F Forward forever; like "tail -f". ESC-F Like F but stop when search pattern is found. r ^R ^L Repaint screen. R Repaint screen, discarding buffered input. --------------------------------------------------- Default "window" is the screen height. Default "half-window" is half of the screen height. --------------------------------------------------------------------------- SEARCHING /pattern * Search forward for (N-th) matching line. ?pattern * Search backward for (N-th) matching line. n * Repeat previous search (for N-th occurrence). N * Repeat previous search in reverse direction. ESC-n * Repeat previous search, spanning files. ESC-N * Repeat previous search, reverse dir. & spanning files. ESC-u Undo (toggle) search highlighting. &pattern * Display only matching lines --------------------------------------------------- A search pattern may begin with one or more of: ^N or ! Search for NON-matching lines. ^E or * Search multiple files (pass thru END OF FILE). ^F or @ Start search at FIRST file (for /) or last file (for ?). ^K Highlight matches, but don't move (KEEP position). ^R Don't use REGULAR EXPRESSIONS. --------------------------------------------------------------------------- JUMPING g < ESC-< * Go to first line in file (or line N). G > ESC-> * Go to last line in file (or line N). p % * Go to beginning of file (or N percent into file). t * Go to the (N-th) next tag. T * Go to the (N-th) previous tag. { ( [ * Find close bracket } ) ]. } ) ] * Find open bracket { ( [. ESC-^F <c1> <c2> * Find close bracket <c2>. ESC-^B <c1> <c2> * Find open bracket <c1> --------------------------------------------------- Each "find close bracket" command goes forward to the close bracket matching the (N-th) open bracket in the top line. Each "find open bracket" command goes backward to the open bracket matching the (N-th) close bracket in the bottom line. m<letter> Mark the current top line with <letter>. M<letter> Mark the current bottom line with <letter>. '<letter> Go to a previously marked position. '' Go to the previous position. ^X^X Same as '. ESC-M<letter> Clear a mark. --------------------------------------------------- A mark is any upper-case or lower-case letter. Certain marks are predefined: ^ means beginning of the file $ means end of the file --------------------------------------------------------------------------- CHANGING FILES :e [file] Examine a new file. ^X^V Same as :e. :n * Examine the (N-th) next file from the command line. :p * Examine the (N-th) previous file from the command line. :x * Examine the first (or N-th) file from the command line. :d Delete the current file from the command line list. = ^G :f Print current file name. --------------------------------------------------------------------------- MISCELLANEOUS COMMANDS -<flag> Toggle a command line option [see OPTIONS below]. --<name> Toggle a command line option, by name. _<flag> Display the setting of a command line option. __<name> Display the setting of an option, by name. +cmd Execute the less cmd each time a new file is examined. !command Execute the shell command with $SHELL. |Xcommand Pipe file between current pos & mark X to shell command. s file Save input to a file. v Edit the current file with $VISUAL or $EDITOR. V Print version number of "less". --------------------------------------------------------------------------- OPTIONS Most options may be changed either on the command line, or from within less by using the - or -- command. Options may be given in one of two forms: either a single character preceded by a -, or a name preceded by --. -? ........ --help Display help (from command line). -a ........ --search-skip-screen Search skips current screen. -A ........ --SEARCH-SKIP-SCREEN Search starts just after target line. -b [N] .... --buffers=[N] Number of buffers. -B ........ --auto-buffers Don't automatically allocate buffers for pipes. -c ........ --clear-screen Repaint by clearing rather than scrolling. -d ........ --dumb Dumb terminal. -D [xn.n] . --color=xn.n Set screen colors. (MS-DOS only) -e -E .... --quit-at-eof --QUIT-AT-EOF Quit at end of file. -f ........ --force Force open non-regular files. -F ........ --quit-if-one-screen Quit if entire file fits on first screen. -g ........ --hilite-search Highlight only last match for searches. -G ........ --HILITE-SEARCH Don't highlight any matches for searches. -h [N] .... --max-back-scroll=[N] Backward scroll limit. -i ........ --ignore-case Ignore case in searches that do not contain uppercase. -I ........ --IGNORE-CASE Ignore case in all searches. -j [N] .... --jump-target=[N] Screen position of target lines. -J ........ --status-column Display a status column at left edge of screen. -k [file] . --lesskey-file=[file] Use a lesskey file. -K ........ --quit-on-intr Exit less in response to ctrl-C. -L ........ --no-lessopen Ignore the LESSOPEN environment variable. -m -M .... --long-prompt --LONG-PROMPT Set prompt style. -n -N .... --line-numbers --LINE-NUMBERS Don't use line numbers. -o [file] . --log-file=[file] Copy to log file (standard input only). -O [file] . --LOG-FILE=[file] Copy to log file (unconditionally overwrite). [2]+ Stopped sudo systemctl status docker cri-dockerd nvidia@nvidia-desktop:~$ # 检查Docker的cgroup驱动 nvidia@nvidia-desktop:~$ docker info | grep -i cgroup Cgroup Driver: systemd Cgroup Version: 1 nvidia@nvidia-desktop:~$ nvidia@nvidia-desktop:~$ # 如果输出是`cgroupfs`,需要改为systemd(与kubelet默认一致) nvidia@nvidia-desktop:~$ sudo tee /etc/docker/daemon.json <<EOF > { > "exec-opts": ["native.cgroupdriver=systemd"] > } > EOF { "exec-opts": ["native.cgroupdriver=systemd"] } nvidia@nvidia-desktop:~$ nvidia@nvidia-desktop:~$ # 应用配置并重启 nvidia@nvidia-desktop:~$ sudo systemctl restart docker nvidia@nvidia-desktop:~$ sudo kubeadm join 192.168.255.178:6443 \ > --token 7kaxfs.m1xlw2b4lloj20h5 \ > --discovery-token-ca-cert-hash sha256:da23339b60f174e254da99411e5799c83e2cc2e103e65dfffececca06ca8d366 \ > --cri-socket unix:///var/run/cri-dockerd.sock \ > --v=5 # 启用详细日志 I1208 14:21:46.917600 313253 join.go:412] [preflight] found NodeName empty; using OS hostname as NodeName [preflight] Running pre-flight checks I1208 14:21:46.917833 313253 preflight.go:93] [preflight] Running general checks I1208 14:21:46.921054 313253 checks.go:280] validating the existence of file /etc/kubernetes/kubelet.conf I1208 14:21:46.921089 313253 checks.go:280] validating the existence of file /etc/kubernetes/bootstrap-kubelet.conf I1208 14:21:46.921403 313253 checks.go:104] validating the container runtime I1208 14:21:46.954045 313253 checks.go:639] validating whether swap is enabled or not [WARNING Swap]: swap is enabled; production deployments should disable swap unless testing the NodeSwap feature gate of the kubelet I1208 14:21:46.954320 313253 checks.go:370] validating the presence of executable crictl I1208 14:21:46.954383 313253 checks.go:370] validating the presence of executable conntrack I1208 14:21:46.954417 313253 checks.go:370] validating the presence of executable ip I1208 14:21:46.954460 313253 checks.go:370] validating the presence of executable iptables I1208 14:21:46.954497 313253 checks.go:370] validating the presence of executable mount I1208 14:21:46.954595 313253 checks.go:370] validating the presence of executable nsenter I1208 14:21:46.954641 313253 checks.go:370] validating the presence of executable ethtool I1208 14:21:46.954669 313253 checks.go:370] validating the presence of executable tc I1208 14:21:46.954692 313253 checks.go:370] validating the presence of executable touch I1208 14:21:46.954747 313253 checks.go:516] running all checks I1208 14:21:46.965096 313253 checks.go:401] checking whether the given node name is valid and reachable using net.LookupHost I1208 14:21:46.965391 313253 checks.go:605] validating kubelet version I1208 14:21:47.033262 313253 checks.go:130] validating if the "kubelet" service is enabled and active I1208 14:21:47.049052 313253 checks.go:203] validating availability of port 10250 I1208 14:21:47.049411 313253 checks.go:280] validating the existence of file /etc/kubernetes/pki/ca.crt I1208 14:21:47.049542 313253 checks.go:430] validating if the connectivity type is via proxy or direct I1208 14:21:47.049633 313253 checks.go:329] validating the contents of file /proc/sys/net/bridge/bridge-nf-call-iptables I1208 14:21:47.049729 313253 checks.go:329] validating the contents of file /proc/sys/net/ipv4/ip_forward I1208 14:21:47.049780 313253 join.go:529] [preflight] Discovering cluster-info I1208 14:21:47.049822 313253 token.go:80] [discovery] Created cluster-info discovery client, requesting info from "192.168.255.178:6443" I1208 14:21:47.088223 313253 token.go:118] [discovery] Requesting info from "192.168.255.178:6443" again to validate TLS against the pinned public key I1208 14:21:47.124104 313253 token.go:135] [discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.255.178:6443" I1208 14:21:47.124143 313253 discovery.go:52] [discovery] Using provided TLSBootstrapToken as authentication credentials for the join process I1208 14:21:47.124173 313253 join.go:543] [preflight] Fetching init configuration I1208 14:21:47.124187 313253 join.go:589] [preflight] Retrieving KubeConfig objects [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' I1208 14:21:47.151294 313253 kubelet.go:74] attempting to download the KubeletConfiguration from ConfigMap "kubelet-config" I1208 14:21:47.166584 313253 interface.go:432] Looking for default routes with IPv4 addresses I1208 14:21:47.166620 313253 interface.go:437] Default route transits interface "wlan0" I1208 14:21:47.167020 313253 interface.go:209] Interface wlan0 is up I1208 14:21:47.167131 313253 interface.go:257] Interface "wlan0" has 4 addresses :[192.168.255.72/24 2409:893d:45c:b5a1:1670:c8e4:2898:1e27/64 2409:893d:45c:b5a1:5f51:491e:9698:9815/64 fe80::417c:e3c1:2dd2:d8db/64]. I1208 14:21:47.167171 313253 interface.go:224] Checking addr 192.168.255.72/24. I1208 14:21:47.167190 313253 interface.go:231] IP found 192.168.255.72 I1208 14:21:47.167208 313253 interface.go:263] Found valid IPv4 address 192.168.255.72 for interface "wlan0". I1208 14:21:47.167218 313253 interface.go:443] Found active IP 192.168.255.72 I1208 14:21:47.172577 313253 preflight.go:104] [preflight] Running configuration dependant checks I1208 14:21:47.172634 313253 controlplaneprepare.go:225] [download-certs] Skipping certs download I1208 14:21:47.172665 313253 kubelet.go:121] [kubelet-start] writing bootstrap kubelet config file at /etc/kubernetes/bootstrap-kubelet.conf I1208 14:21:47.174216 313253 kubelet.go:136] [kubelet-start] writing CA certificate at /etc/kubernetes/pki/ca.crt I1208 14:21:47.175619 313253 kubelet.go:157] [kubelet-start] Checking for an existing Node in the cluster with name "nvidia-desktop" and status "Ready" I1208 14:21:47.186418 313253 kubelet.go:172] [kubelet-start] Stopping the kubelet [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... [kubelet-check] Initial timeout of 40s passed. [kubelet-check] It seems like the kubelet isn't running or healthy. [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused. [kubelet-check] It seems like the kubelet isn't running or healthy. [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused. [kubelet-check] It seems like the kubelet isn't running or healthy. [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused. [kubelet-check] It seems like the kubelet isn't running or healthy. [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp 127.0.0.1:10248: connect: connection refused.
最新发布
12-09
### 解决方案 在 Zsh 中修改 `/proc/sys/net/ipv4/ip_forward` 文件时遇到权限不足的问题,通常是因为该文件的写入权限仅限于超级用户(root)。以下是一些可能的解决方案: #### 1. 使用 `sudo` 提升权限 通过 `sudo` 命令以超级用户权限运行命令可以解决权限不足的问题。例如: ```bash echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null ``` 这里使用了 `tee` 命令来替代直接的重定向操作,因为 `sudo` 无法直接作用于重定向操作符[^1]。 #### 2. 检查当前用户的权限 确保当前用户具有执行 `sudo` 的权限。如果用户未被列入 `sudoers` 文件中,可以通过管理员账户将用户添加到 `sudoers` 文件中。编辑 `sudoers` 文件的方法如下: ```bash sudo visudo ``` 然后在文件中添加类似以下内容: ```plaintext username ALL=(ALL:ALL) ALL ``` 这里的 `username` 是需要授权的用户名。 #### 3. 修改文件权限(不推荐) 虽然可以通过修改 `/proc/sys/net/ipv4/ip_forward` 文件的权限来允许普通用户写入,但这可能会带来安全风险。例如: ```bash sudo chmod 666 /proc/sys/net/ipv4/ip_forward ``` 但这种做法不推荐,因为它会使系统更容易受到攻击。 #### 4. 编写脚本并赋予执行权限 如果需要频繁修改该文件,可以编写一个简单的脚本来完成任务,并将其设置为可执行文件。例如: ```bash #!/bin/bash echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null ``` 保存脚本为 `enable_ip_forward.sh`,然后赋予其执行权限: ```bash chmod +x enable_ip_forward.sh ``` 之后可以通过运行脚本来启用 IP 转发功能。 #### 5. 检查 SELinux 或 AppArmor 配置 如果系统启用了 SELinux 或 AppArmor,这些安全模块可能会限制对 `/proc/sys/net/ipv4/ip_forward` 文件的访问。可以通过以下命令临时禁用 SELinux 来测试: ```bash sudo setenforce 0 ``` 如果问题得以解决,则需要整 SELinux 策略以允许必要的访问。 ### 注意事项 - 修改 `/proc/sys/net/ipv4/ip_forward` 文件会影响系统的网络行为,因此在生产环境中应谨慎操作。 - 如果系统处于多用户环境,建议避免更改文件权限或授予过多用户 `sudo` 权限。 ### 示例代码 以下是一个完整的监控和修改脚本示例,结合了上述方法: ```bash #!/bin/bash while true; do status=$(cat /proc/sys/net/ipv4/ip_forward) if [ "$status" -eq 0 ]; then echo "IP forwarding is disabled. Enabling..." echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null date >> log.txt break fi sleep 1 done ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值