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

          真棒!3 種方法限制 Pod 磁盤容量,瞬間豁然開朗

          共 11846字,需瀏覽 24分鐘

           ·

          2021-04-19 22:00


          Pod 如何使用磁盤

          容器在運(yùn)行期間會(huì)產(chǎn)生臨時(shí)文件、日志。如果沒(méi)有任何配額機(jī)制,則某些容器可能很快將磁盤寫滿,影響宿主機(jī)內(nèi)核和所有應(yīng)用。

          容器的臨時(shí)存儲(chǔ),例如 emptyDir,位于目錄/var/lib/kubelet/pods 下:

          /var/lib/kubelet/pods/
          └── ac0810f5-a1ce-11ea-9caf-00e04c687e45  # POD_ID
              ├── containers
              │   ├── istio-init
              │   │   └── 32390fd7
              │   ├── istio-proxy
              │   │   └── 70ed81da
              │   └── zookeeper
              │       └── e9e21e59
              ├── etc-hosts          # 命名空間的Host文件
              └── volumes            # Pod的卷
                  ├── kubernetes.io~configmap  # ConfigMap類型的卷
                  │   └── istiod-ca-cert
                  │       └── root-cert.pem -> ..data/root-cert.pem
                  ├── kubernetes.io~downward-api
                  │   └── istio-podinfo
                  │       ├── annotations -> ..data/annotations
                  │       └── labels -> ..data/labels
                  ├── kubernetes.io~empty-dir # Empty類型的卷
                  │   ├── istio-data
                  │   └── istio-envoy
                  │       ├── envoy-rev0.json
                  │       └── SDS
                  ├── kubernetes.io~rbd       # RBD卷
                  │   └── pvc-644a7e30-845e-11ea-a4e1-70e24c686d29 # /dev/rbd0掛載到這個(gè)掛載點(diǎn)
                  ├── kubernetes.io~csi       # CSI卷
                  └── kubernetes.io~secret    # Secret類型的卷
                      └── default-token-jp4n8
                          ├── ca.crt -> ..data/ca.crt
                          ├── namespace -> ..data/namespace
                          └── token -> ..data/token

          持久卷的掛載點(diǎn)也位于/var/lib/kubelet/pods 下,但是不會(huì)導(dǎo)致存儲(chǔ)空間的消耗。

          容器的日志,存放在/var/log/pods 目錄下。

          使用 Docker 時(shí),容器的 rootfs位于/var/lib/docker 下,具體位置取決于存儲(chǔ)驅(qū)動(dòng)。

          Pod 驅(qū)逐機(jī)制

          磁盤容量不足觸發(fā)的驅(qū)逐

          具體細(xì)節(jié)參考:/kubernetes-study-note#out-of-resource[1]。

          當(dāng)不可壓縮資源(內(nèi)存、磁盤)不足時(shí),節(jié)點(diǎn)上的 Kubelet 會(huì)嘗試驅(qū)逐掉某些 Pod,以釋放資源,防止整個(gè)系統(tǒng)受到影響。

          其中,磁盤資源不足的信號(hào)來(lái)源有兩個(gè):

          1. imagefs:容器運(yùn)行時(shí)用作存儲(chǔ)鏡像、可寫層的文件系統(tǒng)
          2. nodefs:Kubelet 用作卷、守護(hù)進(jìn)程日志的文件系統(tǒng)

          當(dāng) imagefs 用量到達(dá)驅(qū)逐閾值,Kubelet 會(huì)刪除所有未使用的鏡像,釋放空間。

          當(dāng) nodefs 用量到達(dá)閾值,Kubelet 會(huì)選擇性的驅(qū)逐 Pod(及其容器)來(lái)釋放空間。

          本地臨時(shí)存儲(chǔ)觸發(fā)的驅(qū)逐

          較新版本的 K8S 支持設(shè)置每個(gè) Pod 可以使用的臨時(shí)存儲(chǔ)的 request/limit,驅(qū)逐行為可以更具有針對(duì)性。

          如果 Pod 使用了超過(guò)限制的本地臨時(shí)存儲(chǔ),Kubelet 將設(shè)置驅(qū)逐信號(hào),觸發(fā) Pod 驅(qū)逐流程:

          1. 對(duì)于容器級(jí)別的隔離,如果一個(gè)容器的可寫層、日志占用磁盤超過(guò)限制,則 Kubelet 標(biāo)記 Pod 為待驅(qū)逐
          2. 對(duì)于 Pod 級(jí)別的隔離,Pod 總用量限制,是每個(gè)容器限制之和。如果各容器用量之和+Pod 的 emptyDir 卷超過(guò) Pod 總用量限制,標(biāo)記 Pod 為待驅(qū)逐

          從編排層限制

          從 K8S 1.8 開始,支持本地臨時(shí)存儲(chǔ)(local ephemeral storage),ephemeral 的意思是,數(shù)據(jù)的持久性(durability)不做保證。臨時(shí)存儲(chǔ)可能 Backed by 本地 Attach 的可寫設(shè)備,或者內(nèi)存。

          Pod 可以使用本地臨時(shí)存儲(chǔ)來(lái)作為暫存空間,或者存放緩存、日志。Kubelet 可以利用本地臨時(shí)存儲(chǔ),將 emptyDir 卷掛載給容器。Kubelet 也使用本地臨時(shí)存儲(chǔ)來(lái)保存節(jié)點(diǎn)級(jí)別的容器日志、容器鏡像、容器的可寫層。

          Kubelet 會(huì)將日志寫入到你配置好的日志目錄,默認(rèn) /var/log。其它文件默認(rèn)都寫入到 /var/lib/kubelet。在典型情況下,這兩個(gè)目錄可能都位于宿主機(jī)的 rootfs 之下。

          Kubernetes 支持跟蹤、保留/限制 Pod 能夠使用的本地臨時(shí)存儲(chǔ)的總量。

          限制 Pod 用量

          打開特性開關(guān):LocalStorageCapacityIsolation,可以限制每個(gè) Pod 能夠使用的臨時(shí)存儲(chǔ)的總量。

          注意:以內(nèi)存為媒介(tmpfs)的 emptyDir,其用量計(jì)入容器內(nèi)存消耗,而非本地臨時(shí)存儲(chǔ)消耗。

          使用類似限制內(nèi)存、CPU 用量的方式,限制本地臨時(shí)存儲(chǔ)用量:

          spec.containers[].resources.limits.ephemeral-storage
          spec.containers[].resources.requests.ephemeral-storage

          單位可以是 E, P, T, G, M, K,或者 Ei, Pi, Ti, Gi, Mi, Ki(1024)。

          下面這個(gè)例子,Pod 具有兩個(gè)容器,每個(gè)容器最多使用 4GiB 的本地臨時(shí)存儲(chǔ):

          apiVersion: v1
          kind: Pod
          metadata:
            name: frontend
          spec:
            containers:
            - name: db
              image: mysql
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: "password"
              resources:
                requests:
                  ephemeral-storage: "2Gi"
                limits:
                  ephemeral-storage: "4Gi"
            - name: wp
              image: wordpress
              resources:
                requests:
                  ephemeral-storage: "2Gi"
                limits:
                  ephemeral-storage: "4Gi"

          對(duì) Pod 用量的監(jiān)控

          不監(jiān)控

          如果禁用 Kubelet 對(duì)本地臨時(shí)存儲(chǔ)的監(jiān)控,則 Pod 超過(guò) limit 限制后不會(huì)被驅(qū)逐。但是,如果磁盤整體上容量太低,節(jié)點(diǎn)會(huì)被打上污點(diǎn),所有不能容忍此污點(diǎn)的 Pod 都會(huì)被驅(qū)逐。

          周期性掃描

          Kubelet 可以執(zhí)行周期性的掃描,檢查 emptyDir 卷、容器日志目錄、可寫容器層,然后計(jì)算 Pod/容器使用了多少磁盤。

          這個(gè)模式下有個(gè)問(wèn)題需要注意,Kubelet不會(huì)跟蹤已刪除文件的描述符。也就是說(shuō),如果你創(chuàng)建一個(gè)文件,打開文件,寫入 1GB,然后刪除文件,這種情況下 inode 仍然存在(直到你關(guān)閉文件),空間仍然被占用,但是 Kubelet 卻沒(méi)有算這 1GB.

          Project Quotas

          此特性在 1.15+處于 Alpha 狀態(tài)。

          Project quotas 是 Linux 操作系統(tǒng)級(jí)別的特性,用于在目錄級(jí)別限制磁盤用量。只有本地臨時(shí)存儲(chǔ)(例如 emptyDir)的后備(Backing)文件系統(tǒng)支持 Project quotas,才可以使用該特性。XFS、ext4 都支持 Project quotas。

          K8S 將占用從 1048576 開始的 Project ID,占用中的 ID 注冊(cè)在/etc/projects、/etc/projid 文件中。如果系統(tǒng)中其它進(jìn)程占用 Project ID,則也必須在這兩個(gè)文件中注冊(cè),這樣 K8S 才會(huì)改用其它 ID。

          Quotas 比周期性掃描快,而且更加精準(zhǔn)。當(dāng)一個(gè)目錄被分配到一個(gè) Project 中后,該目錄中創(chuàng)建的任何文件,都是在 Project 中創(chuàng)建的。為了統(tǒng)計(jì)用量,內(nèi)核只需要跟蹤 Project 中創(chuàng)建了多少 block 就可以了。

          如果文件被創(chuàng)建、然后刪除,但是它的文件描述符仍然處于打開狀態(tài),這種情況下,它仍然消耗空間,不會(huì)出現(xiàn)周期性掃描的那種漏統(tǒng)計(jì)的問(wèn)題。

          要啟用 Project Quotas,你需要:

          1. 開啟 Kubelet 特性開關(guān):LocalStorageCapacityIsolationFSQuotaMonitoring

          2. 確保文件系統(tǒng)支持 Project quotas:

            1. XFS 文件系統(tǒng)默認(rèn)支持,不需要操作

            2. ext4 文件系統(tǒng),你需要在未掛載之前,啟用:

              $ sudo tune2fs -O project -Q prjquota /dev/vda
          3. 確保文件系統(tǒng)掛載時(shí),啟用了 Project quotas。使用掛載選項(xiàng) prjquota

          inode 耗盡問(wèn)題

          有的時(shí)候,我們會(huì)發(fā)現(xiàn)磁盤寫入時(shí)會(huì)報(bào)磁盤滿,但是 df 查看容量并沒(méi)有 100%使用,此時(shí)可能只是因?yàn)?inode 耗盡造成的。

          當(dāng)前 k8s 并不支持對(duì) Pod 的臨時(shí)存儲(chǔ)設(shè)置 inode 的 limits/requests。

          但是,如果 node 進(jìn)入了 inode 緊缺的狀態(tài),kubelet 會(huì)將 node 設(shè)置為 under pressure,不再接收新的 Pod 請(qǐng)求。

          從容器引擎限制

          Docker 提供了配置項(xiàng) --storage-opt,可以限制容器占用磁盤空間的大小,此大小影響鏡像和容器文件系統(tǒng),默認(rèn) 10G。

          你也可以在 /etc/docker/daemon.json 中修改此配置項(xiàng):

          {
              "storage-driver""devicemapper",
              "storage-opts": [
                  // devicemapper
                  "dm.basesize=20G",
                  // overlay2
                  "overlay2.size=20G",
              ]
          }

          但是這種配置無(wú)法影響那些掛載的卷,例如 emptyDir。

          從系統(tǒng)層限制

          你可以使用 Linux 系統(tǒng)提供的任何能夠限制磁盤用量的機(jī)制,為了和 K8S 對(duì)接,需要開發(fā) Flexvolume 或 CSI 驅(qū)動(dòng)。

          磁盤配額

          前文已經(jīng)介紹過(guò),K8S 目前支持基于 Project quotas 來(lái)統(tǒng)計(jì) Pod 的磁盤用量。這里簡(jiǎn)單總結(jié)一下 Linux 磁盤配額機(jī)制。

          配額目標(biāo)

          Linux 系統(tǒng)支持以下幾種角度的配額:

          1. 在文件系統(tǒng)級(jí)別,限制群組能夠使用的最大磁盤額度
          2. 在文件系統(tǒng)級(jí)別,限制單個(gè)用戶能夠使用的最大磁盤額度
          3. 限制某個(gè)目錄(directory, project)能夠占用的最大磁盤額度

          前面 2 種配額,現(xiàn)代 Linux 都支持,不需要前提條件。你甚至可以在一個(gè)虛擬的文件系統(tǒng)上進(jìn)行配額:

          # 寫一個(gè)空白文件
          $ dd if=/dev/zero of=/path/to/the/file bs=4096 count=4096
          # 格式化
          ...
          # 掛載為虛擬文件系統(tǒng)
          $ mount -o loop,rw,usrquota,grpquota /path/to/the/file /path/of/mount/point

          # 進(jìn)行配額設(shè)置...

          第 3 種需要較新的文件系統(tǒng),例如 XFS、ext4fs。

          配額角度

          配額可以針對(duì) Block 用量進(jìn)行,也可以針對(duì) inode 用量進(jìn)行。

          配額可以具有軟限制、硬限制。超過(guò)軟限制后,仍然可以正常使用,但是登陸后會(huì)收到警告,在 grace time 倒計(jì)時(shí)完畢之前,用量低于軟限制后,一切恢復(fù)正常。如果 grace time 到期仍然沒(méi)做清理,則無(wú)法創(chuàng)建新文件。

          統(tǒng)計(jì)用量

          啟用配額,內(nèi)核自然需要統(tǒng)計(jì)用量。管理員要查詢用量,可以使用 xfs_quota 這樣的命令,比 du 這種遍歷文件計(jì)算的方式要快得多。

          啟用配額

          在保證底層文件系統(tǒng)支持之后,你需要修改掛載選項(xiàng)來(lái)啟用配額:

          1. uquota/usrquota/quota:針對(duì)用戶設(shè)置配額
          2. gquota/grpquota:針對(duì)群組設(shè)置配額
          3. pquota/prjquota:針對(duì)目錄設(shè)置配額

          LVM

          使用 LVM 你可以任意創(chuàng)建具有尺寸限制的邏輯卷,把這些邏輯卷掛載給 Pod 即可:

          volumes:
          - flexVolume:
              # 編寫的flexVolume驅(qū)動(dòng)放到
              # /usr/libexec/kubernetes/kubelet-plugins/volume/exec/kubernetes.io~lvm/lvm
              driver: kubernetes.io/lvm
              fsType: ext4
              options:
                size: 30Gi
                volumegroup: docker
            name: mnt
          volumeMounts:
            - mountPath: /mnt
              name: mnt

          這需要修改編排方式,不使用 emptyDir 這種本地臨時(shí)存儲(chǔ),還需要處理好邏輯卷清理工作。

          Flexvolume 驅(qū)動(dòng)的示例可以參考:/flexvolume-study-note#lvm[2]。

          參考資料

          1. https://blog.spider.im/post/control-disk-size-in-docker[3]
          2. https://ieevee.com/tech/2019/05/23/ephemeral-storage.html[4]
          3. https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/125.html[5]
          4. https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage[6]
          5. https://coolshell.cn/articles/17200.html[7]

          腳注

          [1]

          /kubernetes-study-note#out-of-resource: https://blog.gmem.cc/kubernetes-study-note#out-of-resource

          [2]

          /flexvolume-study-note#lvm: https://blog.gmem.cc/flexvolume-study-note#lvm

          [3]

          https://blog.spider.im/post/control-disk-size-in-docker: https://blog.spider.im/post/control-disk-size-in-docker/

          [4]

          https://ieevee.com/tech/2019/05/23/ephemeral-storage.html: https://ieevee.com/tech/2019/05/23/ephemeral-storage.html

          [5]

          https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/125.html: https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/125.html

          [6]

          https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#local-ephemeral-storage

          [7]

          https://coolshell.cn/articles/17200.html: https://coolshell.cn/articles/17200.html


          原文鏈接:https://blog.gmem.cc/limit-disk-usage-for-pods



          你可能還喜歡

          點(diǎn)擊下方圖片即可閱讀

          張磊大神的《深入剖析Kubernetes》終于出書啦!

          云原生是一種信仰 ??

          關(guān)注公眾號(hào)

          后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



          點(diǎn)擊 "閱讀原文" 獲取更好的閱讀體驗(yàn)!


          發(fā)現(xiàn)朋友圈變“安靜”了嗎?

          瀏覽 76
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  久草视频观看 | 2018天天弄 | 国产乱伦精品视频 | 在线视频三级 | 69av成人 |