#数据背景:

*100000+ pod

*1300+node

*3集群(单:11Master + 17ETCD)

#遇到的问题:

apiserver 调度,延时问题

Controller 不能及时从 API Server 感知到最新的变化,处理的延时较高

Scheduler 延迟高、吞吐低,无法适应业务日常需求

ETCD架构设计不合理/ETCD稳定性/ETCD性能无法满足业务

发生异常重启时,服务的恢复时间需要几分钟

1、内核层面参数调化
fs.file-max=1000000
# max-file 表示系统级别的能够打开的文件句柄的数量, 一般如果遇到文件句柄达到上限时,会碰到
# "Too many open files"或者Socket/File: Can’t open so many files等错误。
# 配置arp cache 大小
net.ipv4.neigh.default.gc_thresh1=1024
# 存在于ARP高速缓存中的最少层数,如果少于这个数,垃圾收集器将不会运行。缺省值是128。
net.ipv4.neigh.default.gc_thresh2=4096
# 保存在 ARP 高速缓存中的最多的记录软限制。垃圾收集器在开始收集前,允许记录数超过这个数字 5 秒。缺省值是 512。
net.ipv4.neigh.default.gc_thresh3=8192
# 保存在 ARP 高速缓存中的最多记录的硬限制,一旦高速缓存中的数目高于此,垃圾收集器将马上运行。缺省值是1024。
# 以上三个参数,当内核维护的arp表过于庞大时候,可以考虑优化
net.netfilter.nf_conntrack_max=10485760
# 允许的最大跟踪连接条目,是在内核内存中netfilter可以同时处理的“任务”(连接跟踪条目)
net.netfilter.nf_conntrack_tcp_timeout_established=300
net.netfilter.nf_conntrack_buckets=655360
# 哈希表大小(只读)(64位系统、8G内存默认 65536,16G翻倍,如此类推)
net.core.netdev_max_backlog=10000
# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
fs.inotify.max_user_instances=524288
# 默认值: 128 指定了每一个real user ID可创建的inotify instatnces的数量上限
fs.inotify.max_user_watches=524288
# 默认值: 8192 指定了每个inotify instance相关联的watches的上限

2、etcd性能层面优化

#架构层面

搭建高可用的etcd集群, 集群规模增大时可以自动增加etcd节点【二进制单独部署】

#硬件层面

 Etcd对磁盘写入延迟非常敏感,因此对于负载较重的集群,etcd一定要使用local SSD或者高性能云盘。可以使用fio测量磁盘实际顺序 IOPS

3、docker优化
3.1、配置docker daemon并行拉取镜像,以提高镜像拉取效率,在/etc/docker/daemon.json中添加以下配置:
"max-concurrent-downloads": 10
3.2、可以使用local SSD或者高性能云盘作为docker容器的持久数据目录,在/etc/docker/daemon.json中添加以下配置:
"data-root": "/ssd_mount_dir"
3.3、启动pod时都会拉取pause镜像,为了减小拉取pause镜像网络带宽,可以每个node预加载pause镜像,在每个node节点上执行以下命令:
docker load -i /tmp/preloaded_pause_image.tar

#k8s 组件层面优化
4、kubelet参数优化
4.1、设置 --serialize-image-pulls=false, 该选项配置串行拉取镜像,默认值时true,配置为false可以增加并发度。但是如果docker daemon 版本小于 1.9,且使用 aufs 存储则不能改动该选项。
4.2、设置--image-pull-progress-deadline=30, 配置镜像拉取超时。默认值时1分,对于大镜像拉取需要适量增大超时时间。
4.3、kubelet 单节点允许运行的最大 Pod 数:--max-pods=110(默认是 110,可以根据实际需要设置)

4.4、--image-gc-high-threshold 和 --image-gc-low-threshold:这两个参数用于定义 kubelet 中镜像垃圾回收(Garbage Collection)的阈值

#kubelet 状态更新机制

当 Kubernetes 中 Node 节点出现状态异常的情况下,节点上的 Pod 会被重新调度到其他节点上去,但是有的时候我们会发现节点 Down 掉以后,Pod 并不会立即触发重新调度,这实际上就是和 Kubelet 的状态更新机制密切相关的,Kubernetes 提供了一些参数配置来触发重新调度到嗯时间,下面我们来分析下 Kubelet 状态更新的基本流程。

kubelet 自身会定期更新状态到 apiserver,通过参数--node-status-update-frequency=10s指定上报频率,默认是 10s 上报一次。
kube-controller-manager 会每隔--node-monitor-period=5s时间去检查 kubelet 的状态,默认是 5s。
当 node 失联一段时间后,kubernetes 判定 node 为 notready 状态,这段时长通过--node-monitor-grace-period=40s参数配置,默认 40s。  #NodeController 中同步节点状态的周期
当 node 失联一段时间后,kubernetes 判定 node 为 unhealthy 状态,这段时长通过--node-startup-grace-period=1m参数配置,默认 1m0s。#允许运行的节点在标记为不健康之前没有响应的时间
当 node 失联一段时间后,kubernetes 开始删除原 node 上的 pod,这段时长是通过--pod-eviction-timeout=5m0s参数配置,默认 5m0s。      #删除失败节点上的 pods 的宽限期

5、kube-apiserver 参数优化

#apiserver 负载均衡
5.1、设置 --apiserver-count 和 --endpoint-reconciler-type,可使得多个 kube-apiserver 实例加入到 Kubernetes Service 的 endpoints 中,从而实现高可用。

# kube-apiserver 以下两个参数可以控制连接数
5.2、设置 --max-requests-inflight 和 --max-mutating-requests-inflight,默认是 400 和 200。 节点数量在 1000 - 3000 之间时,推荐:
--max-requests-inflight=1500
--max-mutating-requests-inflight=500
节点数量大于 3000 时,推荐:
--max-requests-inflight=3000
--max-mutating-requests-inflight=1000

5.3、当集群中 node 以及 pod 数量非常多时可以稍微调大:

--watch-cache-sizes: 调大resources 的 watch size,默认为 100,比如:--watch-cache-sizes=node#1000, pod#5000

5.4、使用--target-ram-mb配置kube-apiserver的内存,按以下公式得到一个合理的值:
--target-ram-mb=node_nums * 60

5.5、节点故障pod快速迁移容忍周期配置

- --default-not-ready-toleration-seconds=30   #默认300秒,容器迁移对节点不可用状态的容忍时间
- --default-unreachable-toleration-seconds=30  #默认300秒,容器迁移对节点无法访问状态的容忍时间

6、kube-controller-manager参数优化
6.1、kube-controller-manager可以通过 leader election 实现高可用,添加以下命令行参数:
--leader-elect=true
--leader-elect-lease-duration=15s
--leader-elect-renew-deadline=10s
--leader-elect-resource-lock=endpoints
--leader-elect-retry-period=2s
6.2、限制与kube-apiserver通信的qps,--kube-api-qps 默认值20,--kube-api-burst 默认值30 添加以下命令行参数:
--kube-api-qps=100
--kube-api-burst=150

6.3、禁用不需要的 controller:默认启动为 --controllers,即启动所有 controller,可以禁用不需要的 controller

6.4、参数配置

- --concurrent-deployment-syncs=5  #deployment并发处理数,默认5秒,允许同时同步的资源对象的数量。配置数量越大,管理响应越快,但 CPU(和网络)负载也越高

        - - -concurrent-endpoint-syncs=5  #endpoint并发处理数,默认5秒

        - --concurrent-gc-syncs=20 #GC回收工作线程数,默认20秒

        - --concurrent-job-syncs=5 #Job并发处理数,默认5秒

       - --concurrent-namespace-syncs=10 #Namespace并发处理数,默认10秒

       - --concurrent-replicaset-syncs=5 #Replicaset并发处理数,默认5秒

       - --concurrent-resource-quota-syncs=5 #ResourceQuota并发处理数,默认5秒

       - --concurrent-service-syncs=10  #Servicepace并发处理数,默认10秒

       - --concurrent-serviceaccount-token-syncs=5 #ServiceAccountToken并发处理数,默认5秒

       - --concurrent-ttl-after-finished-syncs=5 #TTLAfterFinished并发处理数,默认5秒,取值范围大于等于9 

       - --concurrent-rc-syncs=5 #控制器同时处理资源的数量,默认5秒

       - --horizontal-pod-autoscaler-sync-period=5s #负载弹性伸缩控制器配置,默认5秒 

       - --terminated-pod-gc-threshold=1000 #终止状态pod触发回收的数量阈值,默认1000,取值范围 10-12500

       - --enable-resource-quota=true #启用资源配额管理

# - --controllers=*,deployment.*
7、kube-scheduler参数优化
7.1、kube-scheduler可以通过 leader election 实现高可用,添加以下命令行参数:
--leader-elect=true
--leader-elect-lease-duration=15s
--leader-elect-renew-deadline=10s
--leader-elect-resource-lock=endpoints
--leader-elect-retry-period=2s
7.2、限制与kube-apiserver通信的qps,默认值为 50,burst 默认值为100添加以下命令行参数:
--kube-api-qps=100
--kube-api-burst=150
8、pod优化
8.1、为容器设置资源请求和限制,尤其是一些基础插件服务
spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
spec.containers[].resources.limits.ephemeral-storage
spec.containers[].resources.requests.ephemeral-storage
在k8s中,会根据pod的limit 和 requests的配置将pod划分为不同的qos类别:
* Guaranteed
* Burstable
* BestEffort
当机器可用资源不够时,kubelet会根据qos级别划分迁移驱逐pod。被驱逐的优先级:BestEffort > Burstable > Guaranteed

说明:Guaranteed  requests 和limits 值要相等 ,Burstable   requests 和limits 值不等,BestEffort 值无限制
8.2、对关键应用使用 nodeAffinity、podAffinity 和 podAntiAffinity 等保护,使其调度分散到不同的node上。比如kube-dns配置
8.3、尽量使用控制器来管理容器(如 Deployment、StatefulSet、DaemonSet、Job 等)

9、kubernetes集群数据备份

9.1、etcd数据备份

10、kube-proxy 优化

kube-proxy 默认与 kubelet 同时部署在一台 node 上,可以将 kube-proxy 组件独立部署在非 k8s node 上,避免在所有 node 上都产生大量 iptables 规则

10.1、使用ipvs模式

10.2、独立部署【二进制部署的K8S】

11、镜像优化

使用基于 Alpine Linux、BusyBox 或 Scratch 的轻量级基础镜像
能在一个阶段中执行的业务逻辑就不要放到2个
移除不必要的依赖和文件
镜像使用最小化的操作系统组件
镜像缓存
使用 P2P 进行镜像分发,比如:dragonfly;
基础镜像预加载(一般镜像会分为三层)
第一层:基础镜像即 os
第二层:环境镜像即带有 nginx、tomcat 等服务的镜像
第三层:业务镜像也就是带有业务代码的镜像
基础镜像一般不会频繁更新,可在所有宿主机上预先加载,环境镜像可以定时进行加载,业务镜像则实时拉取

注:节点规模与master 节点规格对比

工作节点数量             master 节点规格

1-5个节点                  4C8G(不建议2C4G)
6-20个节点                4C16G
21-100个节点            8C32G
100-200个节点          16C64G

 

posted on 2023-06-16 10:06  MhaiM  阅读(152)  评论(0编辑  收藏  举报