目錄
前期環境優化
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利用率。