欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解docker容器中的memory限制

 更新時間:2024年04月09日 08:47:53   作者:go4it  
在Docker中,內(nèi)存管理是非常重要的一部分,Docker提供了一些功能來管理容器的內(nèi)存使用情況,其中包括內(nèi)存限制、內(nèi)存交換和內(nèi)存統(tǒng)計等,本文給大家詳細(xì)介紹了docker容器中的memory限制,需要的朋友可以參考下

本文主要研究一下docker容器的memory限制

內(nèi)存限制

docker run -m 512M -p 8081:8080 --rm docker-demo

通過-m參數(shù)指定限制的內(nèi)存大小

buffer/cache

所謂Cache,就是為了彌補(bǔ)高速設(shè)備和低速設(shè)備之間的矛盾而設(shè)立的一個中間層。 緩沖(Buffer)是根據(jù)磁盤的讀寫設(shè)計的,它把分散的寫操作集中進(jìn)行,減少磁盤碎片和硬盤的反復(fù)尋道,從而提高系統(tǒng)性能。

區(qū)別與聯(lián)系

  • 都是為了解決速度不對等的問題。
  • 緩存(Cache)是把讀取過的數(shù)據(jù)保存起來,重新讀取時若命中(找到需要的數(shù)據(jù))就不要去讀硬盤了,若沒有命中再讀硬盤。其中的數(shù)據(jù)會根據(jù)讀取頻率進(jìn)行組織,把最頻繁讀取的內(nèi)容放在最容易找到的位置,把不再讀的內(nèi)容不斷往后排,直至從中刪除。
  • Buffer是即將要被寫入磁盤的,而Cache是被從磁盤中讀出來的。
  • 在應(yīng)用場景上,Buffer是由各種進(jìn)程分配的,被用在如輸入隊列等方面。一個簡單的例子,如某個進(jìn)程要求有多個字段讀入,在所有字段被讀入完整之前,進(jìn)程把先前讀入的字段放在Buffer中保存;Cache經(jīng)常被用在磁盤的I/O請求上,如果有多個進(jìn)程都要訪問某個文件,于是該文件便被做成 Cache以方便下次被訪問,這樣可提高系統(tǒng)性能。比如linux系統(tǒng)中有一個守護(hù)進(jìn)程定期清空緩沖內(nèi)容(即寫入磁盤),也可以通過 sync 命令手動清空緩沖。

操作系統(tǒng)中的Page Cache與Buffer Cache

磁盤數(shù)據(jù)會被讀取到Page Cache進(jìn)行緩存,程序要讀取數(shù)據(jù)的時候,可以直接從Page Cache讀取,這是讀取數(shù)據(jù)的一條線路。 此外,當(dāng)Page Cache的數(shù)據(jù)需要刷新時,Page Cache中的數(shù)據(jù)會交給Buffer Cache,而Buffer Cache中的所有數(shù)據(jù)都會定時刷新到磁盤。這是寫入數(shù)據(jù)的另一條線。 page-cache.png

  • Page Cache:Page Cache是文件系統(tǒng)層級的緩存,它從磁盤里讀取的內(nèi)容都會存儲到這里,這樣程序讀取磁盤內(nèi)容就會非??臁@?,使用grep和find等命令查找內(nèi)容和文件時,第1次會比較慢,再次執(zhí)行就快好多倍,幾乎是瞬間。
  • Buffer Cache:Buffer Cache是磁盤等塊設(shè)備的緩沖,這部分內(nèi)存數(shù)據(jù)是要寫入到磁盤的。這里需要注意,位于內(nèi)存 Buffer 中的數(shù)據(jù)不是即時寫入磁盤的,而是系統(tǒng)空閑或者 Buffer達(dá)到一定大小統(tǒng)一寫到磁盤中,所以斷電易失。為了防止數(shù)據(jù)丟失,最好正常關(guān)機(jī)或者多執(zhí)行幾次sync命令,讓位于Buffer上的數(shù)據(jù)立刻寫到磁盤里。 Page Cache可以極大地提高系統(tǒng)整體性能。例如,進(jìn)程A讀一個文件,內(nèi)核空間會申請Page Cache與此文件對應(yīng),并記錄對應(yīng)關(guān)系,進(jìn)程B再次讀同樣的文件就會直接命中上一次的Page Cache,讀寫速度顯著提升。但注意,Page Cache會根據(jù)LRU算法(最近最少使用)進(jìn)行替換。

實例

top(不支持docker)

top - 09:33:37 up 10 min,  0 users,  load average: 0.03, 0.17, 0.18
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.2 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st
MiB Mem :   1887.4 total,    463.7 free,    438.2 used,    985.6 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   1303.0 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      7 root      20   0 2553756 165584  16608 S   1.0   8.6   0:16.06 java
      1 root      20   0    2388    756    692 S   0.0   0.0   0:00.02 sh
     82 root      20   0    2388   1448   1356 S   0.0   0.1   0:00.01 sh
     98 root      20   0    7980   3100   2672 R   0.0   0.2   0:00.00 top

上面顯示的mem也是宿主機(jī)的,不是docker實例的

free(不支持docker)

# free -h
              total        used        free      shared  buff/cache   available
Mem:          1.8Gi       437Mi       464Mi       2.0Mi       985Mi       1.3Gi
Swap:            0B          0B          0B

這里顯示的是宿主機(jī)的,而非docker的

查看容器內(nèi)存指標(biāo)

# cat /sys/fs/cgroup/memory/memory.usage_in_bytes
240824320
# cat /sys/fs/cgroup/memory/memory.limit_in_bytes
536870912

通過/sys/fs/cgroup/memory/底下的文件查看到的就是docker實例使用的以及docker實例的內(nèi)存限制

docker stats

CONTAINER ID   NAME               CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O   PIDS
7f2f15949afc   practical_spence   0.75%     141.8MiB / 512MiB   27.70%    2.23kB / 0B   0B / 0B     45

docker status這里的MEM USAGE統(tǒng)計的是mem.Usage - mem.Stats["inactive_file"]

// calculateMemUsageUnixNoCache calculate memory usage of the container.
// Cache is intentionally excluded to avoid misinterpretation of the output.
//
// On cgroup v1 host, the result is `mem.Usage - mem.Stats["total_inactive_file"]` .
// On cgroup v2 host, the result is `mem.Usage - mem.Stats["inactive_file"] `.
//
// This definition is consistent with cadvisor and containerd/CRI.
// * https://github.com/google/cadvisor/commit/307d1b1cb320fef66fab02db749f07a459245451
// * https://github.com/containerd/cri/commit/6b8846cdf8b8c98c1d965313d66bc8489166059a
//
// On Docker 19.03 and older, the result was `mem.Usage - mem.Stats["cache"]`.
// See https://github.com/moby/moby/issues/40727 for the background.
func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 {
	// cgroup v1
	if v, isCgroup1 := mem.Stats["total_inactive_file"]; isCgroup1 && v < mem.Usage {
		return float64(mem.Usage - v)
	}
	// cgroup v2
	if v := mem.Stats["inactive_file"]; v < mem.Usage {
		return float64(mem.Usage - v)
	}
	return float64(mem.Usage)
}

func calculateMemPercentUnixNoCache(limit float64, usedNoCache float64) float64 {
	// MemoryStats.Limit will never be 0 unless the container is not running and we haven't
	// got any data from cgroup
	if limit != 0 {
		return usedNoCache / limit * 100.0
	}
	return 0
}

k8s中統(tǒng)計

func decodeMemory(target *resource.Quantity, memStats *stats.MemoryStats) error {
    if memStats == nil || memStats.WorkingSetBytes == nil {
        return fmt.Errorf("missing memory usage metric")
    }

    *target = *uint64Quantity(*memStats.WorkingSetBytes, 0)
    target.Format = resource.BinarySI

    return nil
}

func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) {
    ret.Memory.Usage = s.MemoryStats.Usage.Usage
    ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage
    ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt

    if s.MemoryStats.UseHierarchy {
        ret.Memory.Cache = s.MemoryStats.Stats["total_cache"]
        ret.Memory.RSS = s.MemoryStats.Stats["total_rss"]
        ret.Memory.Swap = s.MemoryStats.Stats["total_swap"]
        ret.Memory.MappedFile = s.MemoryStats.Stats["total_mapped_file"]
    } else {
        ret.Memory.Cache = s.MemoryStats.Stats["cache"]
        ret.Memory.RSS = s.MemoryStats.Stats["rss"]
        ret.Memory.Swap = s.MemoryStats.Stats["swap"]
        ret.Memory.MappedFile = s.MemoryStats.Stats["mapped_file"]
    }
    if v, ok := s.MemoryStats.Stats["pgfault"]; ok {
        ret.Memory.ContainerData.Pgfault = v
        ret.Memory.HierarchicalData.Pgfault = v
    }
    if v, ok := s.MemoryStats.Stats["pgmajfault"]; ok {
        ret.Memory.ContainerData.Pgmajfault = v
        ret.Memory.HierarchicalData.Pgmajfault = v
    }

    workingSet := ret.Memory.Usage
    if v, ok := s.MemoryStats.Stats["total_inactive_file"]; ok {
        if workingSet < v {
            workingSet = 0
        } else {
            workingSet -= v
        }
    }
    ret.Memory.WorkingSet = workingSet
}

kubectl top pod命令查詢到的內(nèi)存使用為Memory WorkingSet = Memory.Usage - memory.stat[total_inactive_file]。 k8s的OOMKiller使用的是container_memory_working_set_bytes指標(biāo),其計算指標(biāo)如下:

container_memory_working_set_bytes 
= container_memory_usage_bytes - total_inactive_file
= total_cache + total_rss - total_inactive_file
= total_inactive_file + total_active_file + total_rss - total_inactive_file
= total_active_file + total_rss

oom killed

        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": true,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 137,
            "Error": "",
            "StartedAt": "2024-04-08T08:34:58.271711439Z",
            "FinishedAt": "2024-04-08T08:35:57.360091044Z"
        }

如果是因為內(nèi)存原因被kill的話,通過docker inspect 容器id,查看State部分,可以看到"OOMKilled": true

小結(jié)

  • docker容器的memory限制使用的是mem.Usage - mem.Stats["inactive_file"]與limit的對比,如果超出則會被kill;free及top顯示的都是宿主機(jī)的內(nèi)存信息
  • kubectl top pod命令是通過memory_working_set(Memory.Usage - memory.stat[total_inactive_file])來統(tǒng)計容器的內(nèi)存使用
  • k8s的OOMKiller使用的是container_memory_working_set_bytes指標(biāo)(total_active_file + total_rss),如果超出該容器的limit,則會被OOMKiller銷毀掉

以上就是一文詳解docker容器中的memory限制的詳細(xì)內(nèi)容,更多關(guān)于docker memory限制的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Docker容器遷移到其他服務(wù)器的5種方法詳解

    Docker容器遷移到其他服務(wù)器的5種方法詳解

    這篇文章主要介紹了Docker容器遷移到其他服務(wù)器的5種方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 如何解決docker commit后鏡像越來越大問題

    如何解決docker commit后鏡像越來越大問題

    解決Docker Commit后鏡像變大問題的方法:方法1直接打包容器并導(dǎo)入為鏡像;方法2將容器根目錄文件壓縮后導(dǎo)入為鏡像,方法1更優(yōu),在其他設(shè)備運(yùn)行時可能出現(xiàn)內(nèi)存不足錯誤
    2025-03-03
  • docker使用http_proxy配置代理解決方法

    docker使用http_proxy配置代理解決方法

    這篇文章主要給大家介紹了關(guān)于docker使用http_proxy配置代理解決方法的相關(guān)資料,Docker HTTP(S) Proxy是一種在Docker容器內(nèi)部設(shè)置 HTTP(S) 代理的方法,以便于容器內(nèi)的應(yīng)用程序可以方便地通過代理訪問互聯(lián)網(wǎng),需要的朋友可以參考下
    2024-05-05
  • docker可視化管理工具portainer忘記密碼重置教程的實現(xiàn)

    docker可視化管理工具portainer忘記密碼重置教程的實現(xiàn)

    本文主要介紹了docker可視化管理工具portainer忘記密碼重置教程的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 在Docker中的ubuntu中安裝Python3和Pip的問題

    在Docker中的ubuntu中安裝Python3和Pip的問題

    這篇文章主要介紹了在Docker中的ubuntu中安裝Python3和Pip的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • dockerfile結(jié)合go應(yīng)用程序的簡單應(yīng)用代碼示例

    dockerfile結(jié)合go應(yīng)用程序的簡單應(yīng)用代碼示例

    Dockerfile文件是一個包含了指令和參數(shù)的文本文件,用于自動化構(gòu)建Docker鏡像,這篇文章主要給大家介紹了關(guān)于dockerfile結(jié)合go應(yīng)用程序的簡單應(yīng)用,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • 使用docker compose安裝harbor私有倉庫的詳細(xì)教程

    使用docker compose安裝harbor私有倉庫的詳細(xì)教程

    harbor鏡像倉庫是由VMware開源的一款企業(yè)級鏡像倉庫,它包括權(quán)限管理(RBAC)、LDAP、日志審核、管理界面、自我注冊、鏡像復(fù)制等諸多功能,本文給大家介紹docker compose安裝harbor的方法,需要的朋友參考下吧
    2021-06-06
  • Docker不能綁定靜態(tài)的外網(wǎng)固定ip的問題及解決辦法

    Docker不能綁定靜態(tài)的外網(wǎng)固定ip的問題及解決辦法

    這篇文章主要介紹了Docker不能綁定靜態(tài)的外網(wǎng)固定ip的問題及解決辦法,需要的朋友可以參考下
    2017-01-01
  • CentOS7虛擬機(jī)安裝并配置docker套件

    CentOS7虛擬機(jī)安裝并配置docker套件

    這篇文章主要介紹了CentOS7虛擬機(jī)安裝并配置docker套件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Docker拉取鏡像的完整步驟

    Docker拉取鏡像的完整步驟

    這篇文章主要給大家介紹了關(guān)于Docker拉取鏡像的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Docker具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評論