K8S集群优化的可执行优化

目录

前期环境优化

1.永久关闭交换分区

2.#加载 ip_vs 模块

3.调整内核参数

4.#使用Systemd管理的Cgroup来进行资源控制与管理

5.开机自启kubelet

6.内核参数优化方案

7.etcd优化

默认etcd空间配额大小为 2G,超过 2G 将不再写入数据。通过给etcd配置 --quota-backend-bytes 参数增大空间配额,最大支持 8G --quota-backend-bytes 8589934592 | header 

7.2.提高etcd对于对等网络流量优先级

7.3.etcd被设计用于元数据的小键值对的处理。

7.4.etcd的备份

8.kubelet优化

8.1增加并发度

8.2.配置镜像拉取超时

8.3.单节点允许运行的最大 Pod 数

9.kube-apiserver优化

9.1.配置kube-apiserver的内存

10.kube-controller-manager优化

10.1.Controller参数配置

10.2.可通过 leader election 实现高可用

10.3.限制与kube-apiserver通信的qps

11.kube-scheduler优化

12.kube-proxy优化

13.pod优化

13.1.为容器设置资源请求和限制

14.如何设置k8s节点的CPU限制

验证:

1)k8s dashboard验证

2. 使用kubectl top命令验证:在Node所在的集群上运行以下命令:


前期环境优化

1.永久关闭交换分区

sed -ri 's/.*swap.*/#&/' /etc/fstab

2.#加载 ip_vs 模块

for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

3.调整内核参数

cat > /etc/sysctl.d/kubernetes.conf << EOF
#开启网桥模式,可将网桥的流量传递给iptables链
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
#关闭ipv6协议
net.ipv6.conf.all.disable_ipv6=1
net.ipv4.ip_forward=1
EOF

//生效参数
sysctl --system 

4.#使用Systemd管理的Cgroup来进行资源控制与管理

因为相对Cgroupfs而言,Systemd限制CPU、内存等资源更加简单和成熟稳定。
#日志使用json-file格式类型存储,大小为100M,保存在/var/log/containers目录下,方便ELK等日志系统收集和管理日志。配置好这里改成500M
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  }
}
EOF

systemctl daemon-reload
systemctl restart docker.service
systemctl enable docker.service     开机自启

5.开机自启kubelet

systemctl enable kubelet.service
#K8S通过kubeadm安装出来以后都是以Pod方式存在,即底层是以容器方式运行,所以kubelet必须设置开机自启

6.内核参数优化方案

cat > /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0                                    #禁止使用 swap 空间,只有当系统内存不足(OOM)时才允许使用它
vm.overcommit_memory=1                            #不检查物理内存是否够用
vm.panic_on_oom=0                                #开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963        ##指定最大文件句柄数
fs.nr_open=52706963        #最大打数                    
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF

补充:(#gc_thresh1 提高到较大的值;此设置的作用是,如果表包含的条目少于 gc_thresh1,内核将永远不会删除(超时)过时的条目。
 
net.core.netdev_max_backlog=16384 # 每CPU网络设备积压队列长度
net.core.rmem_max = 16777216 # 所有协议类型读写的缓存区大小
net.core.wmem_max = 16777216 # 最大的TCP数据发送窗口大小
kernel.pid_max = 4194303 #最大进程数
vm.max_map_count = 262144)


7.etcd优化

7.1.增大etcd的存储限制


默认etcd空间配额大小为 2G,超过 2G 将不再写入数据。通过给etcd配置 --quota-backend-bytes 参数增大空间配额,最大支持 8G
 --quota-backend-bytes 8589934592 | header 
7.2.提高etcd对于对等网络流量优先级

如果etcd leader处理大量并发客户端请求,可能由于网络拥塞而延迟处理follower对等请求。在follower 节点上可能会产生如下的发送缓冲区错误的消息:
dropped MsgProp to 247ae21ff9436b2d since streamMsg's sending buffer is full
dropped MsgAppResp to 247ae21ff9436b2d since streamMsg's sending buffer is full

7.3.etcd被设计用于元数据的小键值对的处理。

较大的请求将工作的同时,可能会增加其他请求的延迟。默认情况下,任何请求的最大大小为1.5 MiB。这个限制可以通过–max-request-bytesetcd服务器的标志来配置。
key的历史记录压缩 ETCD 会存储多版本数据,随着写入的主键增加,历史版本将会越来越多,并且 ETCD 默认不会自动清理历史数据。数据达到 –quota-backend-bytes 设置的配额值时就无法写入数据,必须要压缩并清理历史数据才能继续写入。
--auto-compaction-mode
--auto-compaction-retention
所以,为了避免配额空间耗尽的问题,在创建集群时候建议默认开启历史版本清理功能。


7.4.etcd的备份

所有 Kubernetes 对象都存储在 etcd 上。定期备份 etcd 集群数据对于在灾难场景(例如丢失所有主节点)下恢复 Kubernetes 集群非常重要。快照文件包含所有 Kubernetes 状态和关键信息。为了保证敏感的 Kubernetes 数据的安全,可以对快照文件进行加密。 备份 etcd 集群可以通过两种方式完成: etcd 内置快照和卷快照。

内置快照
etcd 支持内置快照,因此备份 etcd 集群很容易。快照可以从使用 etcdctl snapshot save 命令的活动成员中获取,也可以通过从 etcd 数据目录复制 member/snap/db 文件,该 etcd 数据目录目前没有被 etcd 进程使用。获取快照通常不会影响成员的性能。
下面是一个示例,用于获取 $ENDPOINT 所提供的键空间的快照到文件 snapshotdb:
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb
# exit 0
 
# verify the snapshot
ETCDCTL_API=3 etcdctl --write-out=table snapshot status snapshotdb
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 |       10 |          7 | 2.1 MB     |
+----------+----------+------------+------------+

卷快照
如果 etcd 运行在支持备份的存储卷(如 Amazon Elastic Block 存储)上,则可以通过获取存储卷的快照来备份 etcd 数据。
etcd恢复
etcd 支持从 major.minor 或其他不同 patch 版本的 etcd 进程中获取的快照进行恢复。还原操作用于恢复失败的集群的数据。

在启动还原操作之前,必须有一个快照文件。它可以是来自以前备份操作的快照文件,也可以是来自剩余数据目录的快照文件。 有关从快照文件还原集群的详细信息和示例,请参阅 etcd 灾难恢复文档。

如果还原的集群的访问URL与前一个集群不同,则必须相应地重新配置Kubernetes API 服务器。在本例中,使用参数 –etcd-servers=$NEW_ETCD_CLUSTER 而不是参数–etcd-servers=$OLD_ETCD_CLUSTER 重新启动 Kubernetes API 服务器。用相应的 IP 地址替换 $NEW_ETCD_CLUSTER 和 $OLD_ETCD_CLUSTER。如果在etcd集群前面使用负载平衡,则可能需要更新负载均衡器。

如果大多数etcd成员永久失败,则认为etcd集群失败。在这种情况下,Kubernetes不能对其当前状态进行任何更改。虽然已调度的 pod 可能继续运行,但新的pod无法调度。在这种情况下,恢复etcd 集群并可能需要重新配置Kubernetes API服务器以修复问题。

注意:
如果集群中正在运行任何 API 服务器,则不应尝试还原 etcd 的实例。相反,请按照以下步骤还原 etcd:

停止 所有 kube-apiserver 实例
在所有 etcd 实例中恢复状态
重启所有 kube-apiserver 实例


8.kubelet优化

8.1增加并发度

设置 --serialize-image-pulls=false, 该选项配置串行拉取镜像,默认值时true,配置为false可以增加并发度。但是如果docker daemon 版本小于 1.9,且使用 aufs 存储则不能改动该选项。

--serialize-image-pulls=false

8.2.配置镜像拉取超时

设置--image-pull-progress-deadline=30, 配置镜像拉取超时。默认值时1分,对于大镜像拉取需要适量增大超时时间。

--image-pull-progress-deadline=30

8.3.单节点允许运行的最大 Pod 数

kubelet 单节点允许运行的最大 Pod 数:--max-pods=110(默认是 110,可以根据实际需要设置)

--max-pods=110

9.kube-apiserver优化

ApiServer参数配置
--max-mutating-requests-inflight # 单位时间内的最大修改型请求数量,默认200
--max-requests-inflight # 单位时间内的最大非修改型(读)请求数量,默认400
--watch-cache-sizes # 各类resource的watch cache,默认100,资源数量较多时需要增加

9.1.配置kube-apiserver的内存

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

--target-ram-mb=node_nums * 60


10.kube-controller-manager优化

10.1.Controller参数配置

--node-monitor-period # 检查当前node健康状态的周期间隔,默认5s

--node-monitor-grace-period # 当前node超过了这个指定周期后,即视node为不健康,进入ConditionUnknown状态,默认40s

--pod-eviction-timeout # 当node进入notReady状态后,经过这个指定时间后,会开始驱逐node上的pod,默认5m

--large-cluster-size-threshold # 判断集群是否为大集群,默认为 50,即 50 个节点以上的集群为大集群。

--unhealthy-zone-threshold:# 故障节点数比例,默认为 55%

--node-eviction-rate # 开始对node进行驱逐操作的频率,默认0.1个/s,即每10s最多驱逐某一个node上的pod,避免当master出现问题时,会有批量的node出现异常,这时候如果一次性驱逐过多的node,对master造成额外的压力

--secondary-node-eviction-rate: # 当集群规模大于large-cluster-size-threshold个node时,视为大集群, 集群中只要有55%的node不健康, 就会认为master出现了故障, 会将驱逐速率从0.1降为0.001; 如果集群规模小于large-cluster-size-threshold个node, 集群中出现55%的node不健康,就会停止驱逐。


10.2.可通过 leader election 实现高可用

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

10.3.限制与kube-apiserver通信的qps

调大 –kube-api-qps 值:可以调整至 100,默认值为 20
调大 –kube-api-burst 值:可以调整至 150,默认值为 30
禁用不需要的 controller:kubernetes v1.14 中已有 35 个 controller,默认启动为--controllers,即启动所有 controller,可以禁用不需要的 controller
调整 controller 同步资源的周期:避免过多的资源同步导致集群资源的消耗,所有带有 --concurrent 前缀的参数

限制与kube-apiserver通信的qps,添加以下命令行参数:

--kube-api-qps=100
--kube-api-burst=150

11.kube-scheduler优化

scheduler的配置项比较少,因为调度规则已经是很明确了,不过可以自定义预选和优选策略

--kube-api-qps # 请求apiserver的最大qps,默认50

--policy-config-file # json文件,不指定时使用默认的调度预选和优选策略,可以自定义指定

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

限制与kube-apiserver通信的qps
限制与kube-apiserver通信的qps,添加以下命令行参数:

--kube-api-qps=100
--kube-api-burst=150


12.kube-proxy优化

使用 ipvs 模式 
由于 iptables 匹配时延和规则更新时延在大规模集群中呈指数增长,增加以及删除规则非常耗时,所以需要转为 ipvs,ipvs 使用 hash 表,其增加或者删除一条规则几乎不受规则基数的影响。


13.pod优化

13.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。

使用控制器管理容器

14.如何设置k8s节点的CPU限制

k8s节点的CPU限制可以通过设置k8s调度器的参数来实现,具体步骤如下:

1)打开k8s调度器的配置文件 kube-scheduler.yaml;

2)在spec configuration parameters中找到--kube-reserved参数,并添加如下配置项: --kube-reserved cpu=1000m,memory=1Gi,ephemeral-storage=1Gi

3)修改配置参数--cpu-limit-percent的数值,将其设置为一个合理的值;

4)保存并退出文件。

这里需要注意的是,对于k8s节点的CPU调度限制的设置,需要根据实际情况进行调整,比如内存大小、容器数量、容器类型等因素。一般情况下,k8s节点的CPU调度限制默认为100%,而实际调度节点的CPU利用率一般不会超过80%左右,因此,合理的CPU限制数值应该小于80%。同时为了保证一定的CPU资源用于Node的正常运行,建议将CPU限制调低一些。


验证:


1)k8s dashboard验证

进入k8s dashboard,选择Pods - Nodes选项卡,在Nodes列表中选择需要验证的Node,在该Node的Details选项中找到Allocated Resources的CPU信息,可以看到该节点的CPU利用率是否达到了限制值。

kubectl proxy
http://localhost:8001/api/v1/nodes/your_node_name_here/proxy/ 
访问dashboard即可。

2. 使用kubectl top命令验证:在Node所在的集群上运行以下命令:

kubectl top node
该命令将返回Node的CPU和内存使用情况,以及节点的CPU利用率。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>