<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Kubernetes 資源預(yù)留配置

          共 7799字,需瀏覽 16分鐘

           ·

          2020-09-12 21:09

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

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

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

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

          Node Allocatable

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

          我們可以通過 kubectl describe node 命令查看節(jié)點可分配資源的數(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 兩項內(nèi)容,其中的 Allocatable 就是節(jié)點可被分配的資源,我們這里沒有配置資源預(yù)留,所以默認(rèn)情況下 CapacityAllocatable 的值基本上是一致的。下圖顯示了可分配資源和資源預(yù)留之間的關(guān)系:

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

          節(jié)點可分配資源的計算方式為:

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

          配置資源預(yù)留

          Kube 預(yù)留值

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

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

          比如我們這里修改 node-ydzs4 節(jié)點的 Kube 資源預(yù)留,我們可以直接修改 /var/lib/kubelet/config.yaml 文件來動態(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,啟動會失?。?/p>

          $?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 這個 cgroup 不存在,但是由于子系統(tǒng)較多,具體是哪一個子系統(tǒng)不存在不好定位,我們可以將 kubelet 的日志級別調(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ū)動對應(yīng)的 cgroup 名稱是以 .slice 結(jié)尾的,比如如果你把 cgroup 名稱配置成 kubelet.service,那么對應(yīng)的創(chuàng)建的 cgroup 名稱應(yīng)該為 kubelet.service.slice。如果你配置的是 cgroupfs 的驅(qū)動,則用配置的值即可。無論哪種方式,通過查看錯誤日志都是排查問題最好的方式

          現(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]

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

          $?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

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

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

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

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

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

          $?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)守護進程爭取資源預(yù)留,system-reserved 也應(yīng)該為 kernel 預(yù)留 內(nèi)存,因為目前 kernel 使用的內(nèi)存并不記在 Kubernetes 的 pod 上。但是在執(zhí)行 system-reserved 預(yù)留操作時請加倍小心,因為它可能導(dǎo)致節(jié)點上的關(guān)鍵系統(tǒng)服務(wù) CPU 資源短缺或因為內(nèi)存不足而被終止,所以如果不是自己非常清楚如何配置,可以不用配置系統(tǒng)預(yù)留值。

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

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

          驅(qū)逐閾值

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

          我們這里為 ydzs-node4 節(jié)點配置如下所示的硬驅(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é)點上的可用內(nèi)存降至保留值以下時,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é)點可分配的資源可以看到內(nèi)存減少了,臨時存儲沒有變化是因為硬驅(qū)逐的默認(rèn)值就是 10%。也是符合可分配資源的計算公式的:

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

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




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


          瀏覽 82
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  啪啪AV网站 | 久久视频午夜视频久久 | 久久精品2019中文字幕人妻欧 | 污污久久| 韩日一区 |