▲ 点击上方"DevOps和k8s全栈技术"关注公众号
在k8s部署业务服务pod时,如果将该Pod以k8s svc NodePort类型负载出来,这时压测应用的响应性能较高,可以达到10w多的QPS;将这个k8s svc再用Ingress代理,压测应用发现只有5w多的QPS了。这个性能开销非常大,差了大概一半的性能,所以需要对nginx-ingress-controller进行优化处理。
我们知道,nginx-ingress-controller的原理实际上是扫描Kubernetes集群中的Ingress资源,根据Ingress资源的定义自动为每个域名生成一段nginx虚拟主机及反向代理的配置,最后由nginx读取这些配置,完成实际的HTTP请求流量的处理,整个HTTP请求链路如下:
client ->nginx -> upstream(kubernetes service) -> pods
nginx的实现中必然要对接收的HTTP请求进行7层协议解析,并根据请求信息将HTTP请求转发给upstream。
而client直接请求kubernetes service有不错的QPS值,说明nginx这里存在问题。
1)使用ipvs代替iptables
[root@xianchaomaster1 ~]#yum install -y ipset ipvsadm
[root@xianchaomaster1~]#cat <<'EOF' > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
ipvs_modules=(ip_vsip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_ship_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack_ipv4)
forkernel_module in ${ipvs_modules[*]}; do
/sbin/modinfo -Ffilename ${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ];then
/sbin/modprobe${kernel_module}
fi
done
EOF
[root@xianchaomaster1~]#chmod +x /etc/sysconfig/modules/ipvs.modules
[root@xianchaomaster1~]# /etc/sysconfig/modules/ipvs.modules
[root@xianchaomaster1~]# kubectl -n kube-system edit cm kube-proxy
......
mode:"ipvs"
......
[root@xianchaonode1~]# yum install -y ipset ipvsadm
[root@xianchaonode1~]#cat<<'EOF' > /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
ipvs_modules=(ip_vsip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_ship_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack_ipv4)
forkernel_module in ${ipvs_modules[*]}; do
/sbin/modinfo -Ffilename ${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ];then
/sbin/modprobe${kernel_module}
fi
done
EOF
[root@ xianchaonode1~]# chmod +x /etc/sysconfig/modules/ipvs.modules
[root@ xianchaonode1~]#/etc/sysconfig/modules/ipvs.modules
[root@xianchaomaster1~]# kubectl -n kube-system get pod -l k8s-app=kube-proxy | grep -v 'NAME' | awk'{print $1}' | xargs kubectl -n kube-system delete pod
[root@xianchaomaster1~]# iptables -t filter -F; iptables -t filter -X; iptables -t nat -F; iptables-t nat -X;
[root@ xianchaonode1~]#iptables -t filter -F; iptables -t filter -X; iptables -t nat -F; iptables -tnat -X;
修改ipvs模式之后过5-10分钟测试在k8s创建pod是否可以正常访问网络
[root@xianchaomaster1~]# kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox-- sh
/ # pingwww.baidu.com
PING www.baidu.com(39.156.66.18): 56 data bytes
64 bytes from110.242.68.4: seq=0 ttl=127 time=37.319 ms
#通过上面可以看到能访问网络
/# exit
测试dns是否正常
[root@xianchaomaster1 ~]# kubectl run busybox--image busybox:1.28 --restart=Never --rm -it busybox -- sh
/ # nslookup kubernetes.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default.svc.cluster.local
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
看到上面内容,说明k8s的dns解析正常
2)k8s集群节点修改内核参数
cat <> /etc/sysctl.conf
net.core.somaxcOnn= 655350
net.ipv4.tcp_synCOOKIEs= 1
net.ipv4.tcp_timestamps= 1
net.ipv4.tcp_tw_reuse= 1
net.ipv4.tcp_fin_timeout= 30
net.ipv4.tcp_max_tw_buckets= 5000
net.nf_conntrack_max= 2097152
net.netfilter.nf_conntrack_max= 2097152
net.netfilter.nf_conntrack_tcp_timeout_close_wait= 15
net.netfilter.nf_conntrack_tcp_timeout_fin_wait= 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait= 30
net.netfilter.nf_conntrack_tcp_timeout_established= 1200
EOF
$ sysctl -p –system
3)k8s集群节点修改最大打开文件数
ulimit -n 655350
cat /etc/sysctl.conf
...
fs.file-max=655350
...
sysctl -p--system
cat/etc/security/limits.conf
...
* hard nofile655350
* soft nofile655350
* hard nproc6553
* soft nproc655350
root hard nofile655350
root soft nofile655350
root hard nproc655350
root soft nproc655350
...
echo 'sessionrequired pam_limits.so' >> /etc/pam.d/common-session
4)优化nginx-ingress-controller
参考nginx-ingress-controller的配置方法,这里优化部分如下:
$ kubectl -nkube-system edit configmap nginx-configuration
...
apiVersion: v1
data:
keep-alive:"60"
keep-alive-requests:"100"
upstream-keepalive-connections:"10000"
upstream-keepalive-requests:"100"
upstream-keepalive-timeout:"60"
kind: ConfigMap
...
此时发现性能好多了
么是Keep-Alive模式?
HTTP协议采用请求-应答模式,有普通的非KeepAlive模式,也有KeepAlive模式。
非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。
启用Keep-Alive的优点
启用Keep-Alive模式肯定更高效,性能更高。因为避免了建立/释放连接的开销。下面是RFC 2616 上的总结:
TCP连接更少,这样就会节约TCP连接在建立、释放过程中,主机和路由器上的CPU和内存开销。
网络拥塞也减少了,拿到响应的延时也减少了
错误处理更优雅:不会粗暴地直接关闭连接,而是report,retry
性能大提升的原因
压测命令ab并没有添加-k参数,因此client->nginx的HTTP处理并没有启用Keep-Alive。
但由于nginx-ingress-controller配置了upstream-keepalive-connections、upstream-keepalive-requests、upstream-keepalive-timeout参数,这样nginx->upstream的HTTP处理是启用了Keep-Alive的,这样到Kuberentes Service的TCP连接可以高效地复用,避免了重建连接的开销。
作者微信:luckylucky421302
精彩文章推荐
年底了,总结下这一年,收获满满
2022年底第一波福利!
基于Jenkins+git+harbor+Helm+k8s+Istio构建DevOps流水线
基于k8s+Prometheus+Alertmanager+Grafana构建企业监控告警系统
k8s七层代理Ingress-nginx基于COOKIE、请求头、权重实现灰度发布
如何优化k8s网络插件?
修改k8s kube-proxy代理-由iptables模式变为ipvs模式
k8s控制器Deployment详细介绍:资源清单编写技巧
每周好课推荐
目前有以下几个畅销和高口碑课程,在平台所有课程中排在第一:
(1)热销课->《Docker+K8S+Istio+k8s故障排查+DevOps+Openstack+Openshift+Python+监控+日志收集+Rancher》课程折上折,现在双折扣---->点此立即学习>>https://edu.51cto.com/surl=vGfJG2
(2)福利课->Kubernetes管理员认证 (CKA)购课链接--->
课程地址:https://edu.51cto.com/course/28751.html
(3)安全课->Kubernetes安全专家认证
【零基础入门】K8S CKS认证考试培训 +k8s安全+k8s运维-->
购课链接--->https://edu.51cto.com/topic/5206.html
点亮,服务器10年不宕机
点击阅读原文 | 了解更多