日韩在线人妻伊人|亚洲美女屁股眼交一区二区|精品国产按摩aaa国产精品|美女网站黄色亚洲|www污污污久久|老熟女另类一区一一区|欧美 亚洲 无码|牛牛成人三级电影|精品欧美国产日本懒草在线|先锋影音国内自拍

很抱歉,您尚未登錄!
VIP會員登陸后可以查閱當前板塊內(nèi)容,請登陸后查看!
請點擊登錄

  • TOP
  • 手機版
    全部提示消息

    易之家外貿(mào)SNS社區(qū) Tradesns foreign trade community
    當前所在頁面位置: 首頁 > 貿(mào)易博文 > 深入理解Kubernetes資源限制:內(nèi)存
    深入理解Kubernetes資源限制:內(nèi)存
    瀏覽量:195 | 回復:0 | 發(fā)布時間:2022-08-29 14:29:10

    寫在前面
    當我開始大范圍使用Kubernetes的時候,我開始考慮一個我做實驗時沒有遇到的問題:當集群里的節(jié)點沒有足夠資源的時候,Pod會卡在Pending狀態(tài)。你是沒有辦法給節(jié)點增加CPU或者內(nèi)存的,那么你該怎么做才能將這個Pod從這個節(jié)點拿走?最簡單的辦法是添加另一個節(jié)點,我承認我總是這么干。最終這個策略無法發(fā)揮出Kubernetes最重要的一個能力:即它優(yōu)化計算資源使用的能力。這些場景里面實際的問題并不是節(jié)點太小,而是我們沒有仔細為Pod計算過資源限制。
    資源限制是我們可以向Kubernetes提供的諸多配置之一,它意味著兩點:工作負載運行需要哪些資源;最多允許消費多少資源。第一點對于調(diào)度器而言十分重要,因為它要以此選擇合適的節(jié)點。第二點對于Kubelet非常重要,每個節(jié)點上的守護進程Kubelet負責Pod的運行健康狀態(tài)。大多數(shù)本文的讀者可能對資源限制有一定的了解,實際上這里面有很多有趣的細節(jié)。在這個系列的兩篇文章中我會先仔細分析內(nèi)存資源限制,然后第二篇文章中分析CPU資源限制。

    資源限制
    資源限制是通過每個容器containerSpecresources字段進行設置的,它是v1版本的ResourceRequirements類型的API對象。每個指定了"limits""requests"的對象都可以控制對應的資源。目前只有CPU和內(nèi)存兩種資源。第三種資源類型,持久化存儲仍然是beta版本,我會在以后的博客里進行分析。大多數(shù)情況下,deployment、statefulsetdaemonset的定義里都包含了podSpec和多個containerSpec。這里有個完整的v1資源對象的yaml格式配置:

    這個對象可以這么理解:這個容器通常情況下,需要5%CPU時間和50MiB的內(nèi)存(requests),同時最多允許它使用10%CPU時間和100MiB的內(nèi)存(limits)。我會對requestslimits的區(qū)別做進一步講解,但是一般來說,在調(diào)度的時候requests比較重要,在運行時limits比較重要。盡管資源限制配置在每個容器上,你可以認為Pod的資源限制就是它里面容器的資源限制之和,我們可以從系統(tǒng)的視角觀察到這種關(guān)系。
    內(nèi)存限制
    通常情況下分析內(nèi)存要比分析CPU簡單一些,所以我從這里開始著手。我的一個目標是給大家展示內(nèi)存在系統(tǒng)中是如何實現(xiàn)的,也就是Kubernetes對容器運行時(docker/containerd)所做的工作,容器運行時對Linux內(nèi)核所做的工作。從分析內(nèi)存資源限制開始也為后面分析CPU打好了基礎(chǔ)。首先,讓我們回顧一下前面的例子:

    單位后綴Mi表示的是MiB,所以這個資源對象定義了這個容器需要50MiB并且最多能使用100MiB的內(nèi)存。當然還有其他單位可以進行表示。為了了解如何用這些值是來控制容器進程,我們首先創(chuàng)建一個沒有配置內(nèi)存限制的Pod:
    $ kubectl run limit-test --image=busybox --command -- /bin/sh -c "while true; do sleep 2; done"
    deployment.apps "limit-test" created
    Kubectl命令我們可以驗證這個Pod是沒有資源限制的:
    $ kubectl get pods limit-test-7cff9996fc-zpjps -o=jsonpath='{.spec.containers[0].resources}'
    map[]
    Kubernetes最酷的一點是你可以跳到系統(tǒng)以外的角度來觀察每個構(gòu)成部分,所以我們登錄到運行Pod的節(jié)點,看看Docker是如何運行這個容器的:
    $ docker ps | grep busy | cut -d' ' -f1
    5c3af3101afb
    $ docker inspect 5c3af3101afb -f "{{.HostConfig.Memory}}"

    0這個容器的.HostConfig.Memory域?qū)?/font>docker run時的--memory參數(shù),0值表示未設定。Docker會對這個值做什么?為了控制容器進程能夠訪問的內(nèi)存數(shù)量,Docker配置了一組control group,或者叫cgroup。Cgroup20081月時合并到Linux 2.6.24版本的內(nèi)核。它是一個很重要的話題。我們說cgroup是容器的一組用來控制內(nèi)核如何運行進程的相關(guān)屬性集合。針對內(nèi)存、CPU和各種設備都有對應的cgroupCgroup是具有層級的,這意味著每個cgroup擁有一個它可以繼承屬性的父親,往上一直直到系統(tǒng)啟動時創(chuàng)建的root cgroup。
    Cgroup可以通過/proc/sys偽文件系統(tǒng)輕松查看到,所以檢查容器如何配置內(nèi)存的cgroup就很簡單了。在容器的Pid namespace里,根進程的pid1,但是namespace以外它呈現(xiàn)的是系統(tǒng)級pid,我們可以用來查找它的cgroups
    *$ ps ax | grep /bin/sh
    9513 ?        Ss     0:00 /bin/sh -c while true; do sleep 2; done
    $ sudo cat /proc/9513/cgroup
    ...
    6:memory:/kubepods/burstable/podfbc202d3-da21-11e8-ab5e-42010a80014b/0a1b22ec1361a97c3511db37a4bae932d41b22264e5b97611748f8b662312574
    *
    我列出了內(nèi)存cgroup,這正是我們所關(guān)注的。你在路徑里可以看到前面提到的cgroup層級。一些比較重要的點是:首先,這個路徑是以kubepods開始的cgroup,所以我們的進程繼承了這個group的每個屬性,還有burstable的屬性(KubernetesPod設置為burstable QoS類別)和一組用于審計的Pod表示。最后一段路徑是我們進程實際使用的cgroup。我們可以把它追加到/sys/fs/cgroups/memory后面查看更多信息:
    $ ls -l /sys/fs/cgroup/memory/kubepods/burstable/podfbc202d3-da21-11e8-ab5e-42010a80014b/0a1b22ec1361a97c3511db37a4bae932d41b22264e5b97611748f8b662312574
    ...
    -rw-r--r-- 1 root root 0 Oct 27 19:53 memory.limit_in_bytes
    -rw-r--r-- 1 root root 0 Oct 27 19:53 memory.soft_limit_in_bytes
    再一次,我只列出了我們所關(guān)心的記錄。我們暫時不關(guān)注memory.soft_limit_in_bytes,而將重點轉(zhuǎn)移到memory.limit_in_bytes屬性,它設置了內(nèi)存限制。它等價于Docker命令中的--memory參數(shù),也就是Kubernetes里的內(nèi)存資源限制。我們看看:
    $ sudo cat /sys/fs/cgroup/memory/kubepods/burstable/podfbc202d3-da21-11e8-ab5e-42010a80014b/0a1b22ec1361a97c3511db37a4bae932d41b22264e5b97611748f8b662312574/memory.limit_in_bytes
    9223372036854771712
    這是沒有設置資源限制時我的節(jié)點上顯示的情況。這里有對它的一個簡單的解釋(what-is-the-value-for-the-cgroups-limit-in-bytes-if-the-memory-is-not-restricte)。所以我們看到如果沒有在Kubernetes里設置內(nèi)存限制的話,會導致Docker設置HostConfig.Memory值為0,并進一步導致容器進程被放置在默認值為no limit"memory.limit_in_bytes內(nèi)存cgroup下。我們現(xiàn)在創(chuàng)建使用100MiB內(nèi)存限制的Pod
    $ kubectl run limit-test --image=busybox --limits "memory=100Mi" --command -- /bin/sh -c "while true; do sleep 2; done"
    deployment.apps "limit-test" created
    我們再一次使用kubectl驗證我們的資源配置:
    $ kubectl get pods limit-test-5f5c7dc87d-8qtdx -o=jsonpath='{.spec.containers[0].resources}'
    map[limits:map[memory:100Mi] requests:map[memory:100Mi]]
    你會注意到除了我們設置的limits外,Pod還增加了requests。當你設置limits而沒有設置requests時,Kubernetes默認讓requests等于limits。如果你從調(diào)度器的角度看這是非常有意義的。我會在下面進一步討論requests。當這個Pod啟動后,我們可以看到Docker如何配置的容器以及這個進程的內(nèi)存cgroup
    $ docker ps | grep busy | cut -d' ' -f1
    8fec6c7b6119
    $ docker inspect 8fec6c7b6119 --format '{{.HostConfig.Memory}}'
    104857600
    $ ps ax | grep /bin/sh
    29532 ?      Ss     0:00 /bin/sh -c while true; do sleep 2; done
    $ sudo cat /proc/29532/cgroup
    ...
    6:memory:/kubepods/burstable/pod88f89108-daf7-11e8-b1e1-42010a800070/8fec6c7b61190e74cd9f88286181dd5fa3bbf9cf33c947574eb61462bc254d11
    $ sudo cat /sys/fs/cgroup/memory/kubepods/burstable/pod88f89108-daf7-11e8-b1e1-42010a800070/8fec6c7b61190e74cd9f88286181dd5fa3bbf9cf33c947574eb61462bc254d11/memory.limit_in_bytes
    104857600
    正如你所見,Docker基于我們的containerSpec正確地設置了這個進程的內(nèi)存cgroup。但是這對于運行時意味著什么?Linux內(nèi)存管理是一個復雜的話題,Kubernetes工程師需要知道的是:當一個宿主機遇到了內(nèi)存資源壓力時,內(nèi)核可能會有選擇性地殺死進程。如果一個使用了多于限制內(nèi)存的進程會有更高幾率被殺死。因為Kubernetes的任務是盡可能多地向這些節(jié)點上安排Pod,這會導致節(jié)點內(nèi)存壓力異常。如果你的容器使用了過多內(nèi)存,那么它很可能會被oom-killed。如果Docker收到了內(nèi)核的通知,Kubernetes會找到這個容器并依據(jù)設置嘗試重啟這個Pod。
    所以Kubernetes默認創(chuàng)建的內(nèi)存requests是什么?擁有一個100MiB的內(nèi)存請求會影響到cgroup?可能它設置了我們之前看到的memory.soft_limit_in_bytes?讓我們看看:
    $ sudo cat /sys/fs/cgroup/memory/kubepods/burstable/pod88f89108-daf7-11e8-b1e1-42010a800070/8fec6c7b61190e74cd9f88286181dd5fa3bbf9cf33c947574eb61462bc254d11/memory.soft_limit_in_bytes
    9223372036854771712

    你可以看到軟限制仍然被設置為默認值“no limit”。即使Docker支持通過參數(shù)--memory-reservation進行設置,但Kubernetes并不支持這個參數(shù)。這是否意味著為你的容器指定內(nèi)存requests并不重要?不,不是的。requests要比limits更重要。limits告訴Linux內(nèi)核什么時候你的進程可以為了清理空間而被殺死。requests幫助Kubernetes調(diào)度找到合適的節(jié)點運行Pod。如果不設置它們,或者設置得非常低,那么可能會有不好的影響。

    IPLC專線是純內(nèi)網(wǎng)的專線,穩(wěn)定性好,延時低,對網(wǎng)絡品質(zhì)有要求的核心產(chǎn)品,可以通過使用IPLC專線服務來提升網(wǎng)絡體驗和服務。

    例如,假設你沒有配置內(nèi)存
    requests來運行Pod,而配置了一個較高的limits。正如我們所知道的Kubernetes默認會把requests的值指向limits,如果沒有合適的資源的節(jié)點的話,Pod可能會調(diào)度失敗,即使它實際需要的資源并沒有那么多。另一方面,如果你運行了一個配置了較低requests值的Pod,你其實是在鼓勵內(nèi)核oom-kill掉它。為什么?假設你的Pod通常使用100MiB內(nèi)存,你卻只為它配置了50MiB內(nèi)存requests。如果你有一個擁有75MiB內(nèi)存空間的節(jié)點,那么這個Pod會被調(diào)度到這個節(jié)點。當Pod內(nèi)存消耗擴大到100MiB時,會讓這個節(jié)點壓力變大,這個時候內(nèi)核可能會選擇殺掉你的進程。所以我們要正確配置Pod的內(nèi)存requestslimits。

    關(guān) 注 (0
    評 論(0)
    分 享
    熱門
    相關(guān)
    淘寶店鋪產(chǎn)品拍攝模板
    作者
    王桂江
    回復:0 | 發(fā)布時間:2025-08-20 09:11:51
    Significance of PLA materials in sustainable development
    作者
    LuoEmerie
    回復:0 | 發(fā)布時間:2025-08-19 14:51:48