1. Kubernetes 資源預(yù)留配置

        共 7799字,需瀏覽 16分鐘

         ·

        2020-09-12 21:09

        Kubernetes 的節(jié)點(diǎn)可以按照節(jié)點(diǎn)的資源容量進(jìn)行調(diào)度,默認(rèn)情況下 Pod 能夠使用節(jié)點(diǎn)全部可用容量。這樣就會(huì)造成一個(gè)問題,因?yàn)楣?jié)點(diǎn)自己通常運(yùn)行了不少驅(qū)動(dòng) OS 和 Kubernetes 的系統(tǒng)守護(hù)進(jìn)程。除非為這些系統(tǒng)守護(hù)進(jìn)程留出資源,否則它們將與 Pod 爭奪資源并導(dǎo)致節(jié)點(diǎn)資源短缺問題。

        當(dāng)我們在線上使用 Kubernetes 集群的時(shí)候,如果沒有對節(jié)點(diǎn)配置正確的資源預(yù)留,我們可以考慮一個(gè)場景,由于某個(gè)應(yīng)用無限制的使用節(jié)點(diǎn)的 CPU 資源,導(dǎo)致節(jié)點(diǎn)上 CPU 使用持續(xù)100%運(yùn)行,而且壓榨到了 kubelet 組件的 CPU 使用,這樣就會(huì)導(dǎo)致 kubelet 和 apiserver 的心跳出問題,節(jié)點(diǎn)就會(huì)出現(xiàn) Not Ready 狀況了。默認(rèn)情況下節(jié)點(diǎn) Not Ready 過后,5分鐘后會(huì)驅(qū)逐應(yīng)用到其他節(jié)點(diǎn),當(dāng)這個(gè)應(yīng)用跑到其他節(jié)點(diǎn)上的時(shí)候同樣100%的使用 CPU,是不是也會(huì)把這個(gè)節(jié)點(diǎn)搞掛掉,同樣的情況繼續(xù)下去,也就導(dǎo)致了整個(gè)集群的雪崩,集群內(nèi)的節(jié)點(diǎn)一個(gè)一個(gè)的 Not Ready 了,后果是非常嚴(yán)重的,或多或少的人遇到過 Kubernetes 集群雪崩的情況,這個(gè)問題也是面試的時(shí)候鏡像詢問的問題。

        要解決這個(gè)問題就需要為 Kubernetes 集群配置資源預(yù)留,kubelet 暴露了一個(gè)名為 Node Allocatable 的特性,有助于為系統(tǒng)守護(hù)進(jìn)程預(yù)留計(jì)算資源,Kubernetes 也是推薦集群管理員按照每個(gè)節(jié)點(diǎn)上的工作負(fù)載來配置 Node Allocatable。

        本文的操作環(huán)境為 Kubernetes V1.17.11 版本,Docker 和 Kubelet 采用的 cgroup 驅(qū)動(dòng)為 systemd。

        Node Allocatable

        Kubernetes 節(jié)點(diǎn)上的 Allocatable 被定義為 Pod 可用計(jì)算資源量,調(diào)度器不會(huì)超額申請 Allocatable,目前支持 CPU, memory 和 ephemeral-storage 這幾個(gè)參數(shù)。

        我們可以通過 kubectl describe node 命令查看節(jié)點(diǎn)可分配資源的數(shù)據(jù):

        $?kubectl?describe?node?ydzs-node4
        ......
        Capacity:
        ??cpu:????????????????4
        ??ephemeral-storage:??17921Mi
        ??hugepages-2Mi:??????0
        ??memory:?????????????8008820Ki
        ??pods:???????????????110
        Allocatable:
        ??cpu:????????????????4
        ??ephemeral-storage:??16912377419
        ??hugepages-2Mi:??????0
        ??memory:?????????????7906420Ki
        ??pods:???????????????110
        ......

        可以看到其中有 CapacityAllocatable 兩項(xiàng)內(nèi)容,其中的 Allocatable 就是節(jié)點(diǎn)可被分配的資源,我們這里沒有配置資源預(yù)留,所以默認(rèn)情況下 CapacityAllocatable 的值基本上是一致的。下圖顯示了可分配資源和資源預(yù)留之間的關(guān)系:

        Node Allocatable
        • Kubelet Node Allocatable 用來為 Kube 組件和 System 進(jìn)程預(yù)留資源,從而保證當(dāng)節(jié)點(diǎn)出現(xiàn)滿負(fù)荷時(shí)也能保證 Kube 和 System 進(jìn)程有足夠的資源。
        • 目前支持 cpu, memory, ephemeral-storage 三種資源預(yù)留。
        • Node Capacity 是節(jié)點(diǎn)的所有硬件資源,kube-reserved 是給 kube 組件預(yù)留的資源,system-reserved 是給系統(tǒng)進(jìn)程預(yù)留的資源,eviction-threshold 是 kubelet 驅(qū)逐的閾值設(shè)定,allocatable 才是真正調(diào)度器調(diào)度 Pod 時(shí)的參考值(保證節(jié)點(diǎn)上所有 Pods 的 request 資源不超過Allocatable)。

        節(jié)點(diǎn)可分配資源的計(jì)算方式為:

        Node?Allocatable?Resource?=?Node?Capacity?-?Kube-reserved?-?system-reserved?-?eviction-threshold

        配置資源預(yù)留

        Kube 預(yù)留值

        首先我們來配置 Kube 預(yù)留值,kube-reserved 是為了給諸如 kubelet、容器運(yùn)行時(shí)、node problem detector 等 kubernetes 系統(tǒng)守護(hù)進(jìn)程爭取資源預(yù)留。要配置 Kube 預(yù)留,需要把 kubelet 的 --kube-reserved-cgroup 標(biāo)志的值設(shè)置為 kube 守護(hù)進(jìn)程的父控制組。

        不過需要注意,如果 --kube-reserved-cgroup 不存在,Kubelet 不會(huì)創(chuàng)建它,啟動(dòng) Kubelet 將會(huì)失敗。

        比如我們這里修改 node-ydzs4 節(jié)點(diǎn)的 Kube 資源預(yù)留,我們可以直接修改 /var/lib/kubelet/config.yaml 文件來動(dòng)態(tài)配置 kubelet,添加如下所示的資源預(yù)留配置:

        apiVersion:?kubelet.config.k8s.io/v1beta1
        ......
        enforceNodeAllocatable:
        -?pods
        -?kube-reserved??#?開啟?kube?資源預(yù)留
        kubeReserved:
        ??cpu:?500m
        ??memory:?1Gi
        ??ephemeral-storage:?1Gi
        kubeReservedCgroup:?/kubelet.slice??#?指定?kube?資源預(yù)留的?cgroup

        修改完成后,重啟 kubelet,如果沒有創(chuàng)建上面的 kubelet 的 cgroup,啟動(dòng)會(huì)失敗:

        $?systemctl?restart?kubelet
        $?journalctl?-u?kubelet?-f
        ......
        Aug?11?15:04:13?ydzs-node4?kubelet[28843]:?F0811?15:04:13.653476???28843?kubelet.go:1380]?Failed?to?start?ContainerManager?Failed?to?enforce?Kube?Reserved?Cgroup?Limits?on?"/kubelet.slice":?["kubelet"]?cgroup?does?not?exist

        上面的提示信息很明顯,我們指定的 kubelet 這個(gè) cgroup 不存在,但是由于子系統(tǒng)較多,具體是哪一個(gè)子系統(tǒng)不存在不好定位,我們可以將 kubelet 的日志級(jí)別調(diào)整為 v=4,就可以看到具體丟失的 cgroup 路徑:

        $?vi?/var/lib/kubelet/kubeadm-flags.env
        KUBELET_KUBEADM_ARGS="--v=4?--cgroup-driver=systemd?--network-plugin=cni"

        然后再次重啟 kubelet:

        $?systemctl?daemon-reload
        $?systemctl?restart?kubelet

        再次查看 kubelet 日志:

        $?journalctl?-u?kubelet?-f
        ......
        Sep?09?17:57:36?ydzs-node4?kubelet[20427]:?I0909?17:57:36.382811???20427?cgroup_manager_linux.go:273]?The?Cgroup?[kubelet]?has?some?missing?paths:?[/sys/fs/cgroup/cpu,cpuacct/kubelet.slice?/sys/fs/cgroup/memory/kubelet.slice?/sys/fs/cgroup/systemd/kubelet.slice?/sys/fs/cgroup/pids/kubelet.slice?/sys/fs/cgroup/cpu,cpuacct/kubelet.slice?/sys/fs/cgroup/cpuset/kubelet.slice]
        Sep?09?17:57:36?ydzs-node4?kubelet[20427]:?I0909?17:57:36.383002???20427?factory.go:170]?Factory?"systemd"?can?handle?container?"/system.slice/run-docker-netns-db100461211c.mount",?but?ignoring.
        Sep?09?17:57:36?ydzs-node4?kubelet[20427]:?I0909?17:57:36.383025???20427?manager.go:908]?ignoring?container?"/system.slice/run-docker-netns-db100461211c.mount"
        Sep?09?17:57:36?ydzs-node4?kubelet[20427]:?F0909?17:57:36.383046???20427?kubelet.go:1381]?Failed?to?start?ContainerManager?Failed?to?enforce?Kube?Reserved?Cgroup?Limits?on?"/kubelet.slice":?["kubelet"]?cgroup?does?not?exist

        注意:systemd 的 cgroup 驅(qū)動(dòng)對應(yīng)的 cgroup 名稱是以 .slice 結(jié)尾的,比如如果你把 cgroup 名稱配置成 kubelet.service,那么對應(yīng)的創(chuàng)建的 cgroup 名稱應(yīng)該為 kubelet.service.slice。如果你配置的是 cgroupfs 的驅(qū)動(dòng),則用配置的值即可。無論哪種方式,通過查看錯(cuò)誤日志都是排查問題最好的方式

        現(xiàn)在可以看到具體的 cgroup 不存在的路徑信息了:

        The?Cgroup?[kubelet]?has?some?missing?paths:?[/sys/fs/cgroup/cpu,cpuacct/kubelet.slice?/sys/fs/cgroup/memory/kubelet.slice?/sys/fs/cgroup/systemd/kubelet.slice?/sys/fs/cgroup/pids/kubelet.slice?/sys/fs/cgroup/cpu,cpuacct/kubelet.slice?/sys/fs/cgroup/cpuset/kubelet.slice]

        所以要解決這個(gè)問題也很簡單,我們只需要?jiǎng)?chuàng)建上面的幾個(gè)路徑即可:

        $?mkdir?-p?/sys/fs/cgroup/cpu,cpuacct/kubelet.slice
        $?mkdir?-p?/sys/fs/cgroup/memory/kubelet.slice
        $?mkdir?-p?/sys/fs/cgroup/systemd/kubelet.slice
        $?mkdir?-p?/sys/fs/cgroup/pids/kubelet.slice
        $?mkdir?-p?/sys/fs/cgroup/cpu,cpuacct/kubelet.slice
        $?mkdir?-p?/sys/fs/cgroup/cpuset/kubelet.slice

        創(chuàng)建完成后,再次重啟:

        $?systemctl?restart?kubelet
        $?journalctl?-u?kubelet?-f
        ......
        Sep?09?17:59:41?ydzs-node4?kubelet[21462]:?F0909?17:59:41.291957???21462?kubelet.go:1381]?Failed?to?start?ContainerManager?Failed?to?enforce?Kube?Reserved?Cgroup?Limits?on?"/kubelet.slice":?failed?to?set?supported?cgroup?subsystems?for?cgroup?[kubelet]:?failed?to?set?config?for?supported?subsystems?:?failed?to?write?0?to?hugetlb.2MB.limit_in_bytes:?open?/sys/fs/cgroup/hugetlb/kubelet.slice/hugetlb.2MB.limit_in_bytes:?no?such?file?or?directory

        可以看到還有一個(gè) hugetlb 的 cgroup 路徑不存在,所以繼續(xù)創(chuàng)建這個(gè)路徑:

        $?mkdir?-p?/sys/fs/cgroup/hugetlb/kubelet.slice
        $?systemctl?restart?kubelet

        重啟完成后就可以正常啟動(dòng)了,啟動(dòng)完成后我們可以通過查看 cgroup 里面的限制信息校驗(yàn)是否配置成功,比如我們查看內(nèi)存的限制信息:

        $?cat?/sys/fs/cgroup/memory/kubelet.slice/memory.limit_in_bytes
        1073741824??#?1Gi

        現(xiàn)在再次查看節(jié)點(diǎn)的信息:

        $?kubectl?describe?node?ydzs-node4
        ......
        Addresses:
        ??InternalIP:??10.151.30.59
        ??Hostname:????ydzs-node4
        Capacity:
        ??cpu:????????????????4
        ??ephemeral-storage:??17921Mi
        ??hugepages-2Mi:??????0
        ??memory:?????????????8008820Ki
        ??pods:???????????????110
        Allocatable:
        ??cpu:????????????????3500m
        ??ephemeral-storage:??15838635595
        ??hugepages-2Mi:??????0
        ??memory:?????????????6857844Ki
        ??pods:???????????????110
        ......

        可以看到可以分配的 Allocatable 值就變成了 Kube 預(yù)留過后的值了,證明我們的 Kube 預(yù)留成功了。

        系統(tǒng)預(yù)留值

        我們也可以用同樣的方式為系統(tǒng)配置預(yù)留值,system-reserved 用于為諸如 sshd、udev 等系統(tǒng)守護(hù)進(jìn)程爭取資源預(yù)留,system-reserved 也應(yīng)該為 kernel 預(yù)留 內(nèi)存,因?yàn)槟壳?kernel 使用的內(nèi)存并不記在 Kubernetes 的 pod 上。但是在執(zhí)行 system-reserved 預(yù)留操作時(shí)請加倍小心,因?yàn)樗赡軐?dǎo)致節(jié)點(diǎn)上的關(guān)鍵系統(tǒng)服務(wù) CPU 資源短缺或因?yàn)閮?nèi)存不足而被終止,所以如果不是自己非常清楚如何配置,可以不用配置系統(tǒng)預(yù)留值。

        同樣通過 kubelet 的參數(shù) --system-reserved 配置系統(tǒng)預(yù)留值,但是也需要配置 --system-reserved-cgroup 參數(shù)為系統(tǒng)進(jìn)程設(shè)置 cgroup。

        請注意,如果 --system-reserved-cgroup 不存在,kubelet 不會(huì)創(chuàng)建它,kubelet 會(huì)啟動(dòng)失敗。

        驅(qū)逐閾值

        上面我們還提到可分配的資源還和 kubelet 驅(qū)逐的閾值有關(guān)。節(jié)點(diǎn)級(jí)別的內(nèi)存壓力將導(dǎo)致系統(tǒng)內(nèi)存不足,這將影響到整個(gè)節(jié)點(diǎn)及其上運(yùn)行的所有 Pod,節(jié)點(diǎn)可以暫時(shí)離線直到內(nèi)存已經(jīng)回收為止,我們可以通過配置 kubelet 驅(qū)逐閾值來防止系統(tǒng)內(nèi)存不足。驅(qū)逐操作只支持內(nèi)存和 ephemeral-storage 兩種不可壓縮資源。當(dāng)出現(xiàn)內(nèi)存不足時(shí),調(diào)度器不會(huì)調(diào)度新的 Best-Effort QoS Pods 到此節(jié)點(diǎn),當(dāng)出現(xiàn)磁盤壓力時(shí),調(diào)度器不會(huì)調(diào)度任何新 Pods 到此節(jié)點(diǎn)。

        我們這里為 ydzs-node4 節(jié)點(diǎn)配置如下所示的硬驅(qū)逐閾值:

        #?/var/lib/kubelet/config.yaml
        ......
        evictionHard:??#?配置硬驅(qū)逐閾值
        ??memory.available:?"300Mi"
        ??nodefs.available:?"10%"
        enforceNodeAllocatable:
        -?pods
        -?kube-reserved
        kubeReserved:
        ??cpu:?500m
        ??memory:?1Gi
        ??ephemeral-storage:?1Gi
        kubeReservedCgroup:?/kubelet.slice
        ......

        我們通過 --eviction-hard 預(yù)留一些內(nèi)存后,當(dāng)節(jié)點(diǎn)上的可用內(nèi)存降至保留值以下時(shí),kubelet 將嘗試驅(qū)逐 Pod,

        $?kubectl?describe?node?ydzs-node4
        ......
        Addresses:
        ??InternalIP:??10.151.30.59
        ??Hostname:????ydzs-node4
        Capacity:
        ??cpu:????????????????4
        ??ephemeral-storage:??17921Mi
        ??hugepages-2Mi:??????0
        ??memory:?????????????8008820Ki
        ??pods:???????????????110
        Allocatable:
        ??cpu:????????????????3500m
        ??ephemeral-storage:??15838635595
        ??hugepages-2Mi:??????0
        ??memory:?????????????6653044Ki
        ??pods:???????????????110
        ......

        配置生效后再次查看節(jié)點(diǎn)可分配的資源可以看到內(nèi)存減少了,臨時(shí)存儲(chǔ)沒有變化是因?yàn)橛豺?qū)逐的默認(rèn)值就是 10%。也是符合可分配資源的計(jì)算公式的:

        Node?Allocatable?Resource?=?Node?Capacity?-?Kube-reserved?-?system-reserved?-?eviction-threshold

        到這里我們就完成了 Kubernetes 資源預(yù)留的配置。




        K8S進(jìn)階訓(xùn)練營,點(diǎn)擊下方圖片了解詳情


        瀏覽 82
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
          
          

            1. 美日韩无码视频 | 鸡吧操逼视频 | 国产精品爽爽久久久天 | 国产超级无码高清在线视频观看 | 91成人电影 |