日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

深入剖析 Linux Cgroups 子系统:资源精细管理

發布時間:2024/1/16 linux 46 coder
生活随笔 收集整理的這篇文章主要介紹了 深入剖析 Linux Cgroups 子系统:资源精细管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本章主要演示以下 cgroups 下各個 subsystem 的作用。

根據難易程度,依次演示了 pids 、cpu 和 memory 3 個 subsystem 的使用。

注:本文所有操作在 Ubuntu20.04 下進行。


如果你對云原生技術充滿好奇,想要深入了解更多相關的文章和資訊,歡迎關注微信公眾號。

搜索公眾號【探索云原生】即可訂閱


1. pids

pids subsystem 功能是限制 cgroup 及其所有子孫 cgroup 里面能創建的總的 task 數量

注意:這里的 task 指通過 fork 和 clone 函數創建的進程,由于 clone 函數也能創建線程(在 Linux 里面,線程是一種特殊的進程),所以這里的 task 也包含線程。

本文統一以進程來代表 task,即本文中的進程代表了進程和線程>

創建子 cgroup

創建子 cgroup,取名為 test

#進入目錄/sys/fs/cgroup/pids/并新建一個目錄,即創建了一個子cgroup
lixd  /home/lixd $ cd /sys/fs/cgroup/pids
lixd  /sys/fs/cgroup/pids $ sudo mkdir test

再來看看 test 目錄下的文件

lixd  /sys/fs/cgroup/pids $ cd test
#除了上一篇中介紹的那些文件外,多了兩個文件
 lixd  /sys/fs/cgroup/pids/test $ ls
cgroup.clone_children  cgroup.procs  notify_on_release  pids.current  pids.events  pids.max  tasks

下面是這兩個文件的含義:

  • pids.current: 表示當前 cgroup 及其所有子孫 cgroup 中現有的總的進程數量
  • pids.max: 當前 cgroup 及其所有子孫 cgroup 中所允許創建的總的最大進程數量

限制進程數

首先是將當前 bash 加入到 cgroup 中,并修改pids.max的值,為了便于測試,這里就限制為 1:

#--------------------------第一個shell窗口----------------------
# 將當前bash進程加入到該cgroup
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/pids/test# echo $$ > cgroup.procs
#將pids.max設置為1,即當前cgroup只允許有一個進程
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/pids/test# echo 1 > pids.max

由于 bash 已經占用了一個進程,所以此時 bash 中已經無法創建新的進程了:

root@DESKTOP-9K4GB6E:/sys/fs/cgroup/pids/test# ls
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable
bash: fork: retry: Resource temporarily unavailable

創建新進程失敗,于是命令運行失敗,說明限制生效。

打開另一個 shell 查看

 lixd  /mnt/c/Users/意琦行 $ cd /sys/fs/cgroup/pids/test
 lixd  /sys/fs/cgroup/pids/test $ ls
cgroup.clone_children  cgroup.procs  notify_on_release  pids.current  pids.events  pids.max  tasks
 lixd  /sys/fs/cgroup/pids/test $ cat pids.current
1

果然,pids.current 為 1,已經到 pids.max 的限制了。

當前 cgroup 和子 cgroup 之間的關系

當前 cgroup 中的 pids.currentpids.max 代表了當前 cgroup 及所有子孫 cgroup 的所有進程,所以子孫 cgroup 中的 pids.max 大小不能超過父 cgroup。

如果子 cgroup 中的 pids.max 設置的大于父 cgroup 里的值,會怎么樣?

答案是子 cgroup 中的進程不光受子 cgroup 限制,還要受其父 cgroup 的限制。

#繼續使用上面的兩個窗口
#--------------------------第二個shell窗口----------------------
#將pids.max設置成2
dev@dev:/sys/fs/cgroup/pids/test$ echo 2 > pids.max
#在test下面創建一個子cgroup
dev@dev:/sys/fs/cgroup/pids/test$ mkdir subtest
dev@dev:/sys/fs/cgroup/pids/test$ cd subtest/
#將subtest的pids.max設置為5
dev@dev:/sys/fs/cgroup/pids/test/subtest$ echo 5 > pids.max
#將當前bash進程加入到subtest中
dev@dev:/sys/fs/cgroup/pids/test/subtest$ echo $$ > cgroup.procs
#--------------------------第三個shell窗口----------------------
#重新打開一個bash窗口,看一下test和subtest里面的數據
#test里面的數據如下:
dev@dev:~$ cd /sys/fs/cgroup/pids/test
dev@dev:/sys/fs/cgroup/pids/test$ cat pids.max
2
#這里為2表示目前test和subtest里面總的進程數為2
dev@dev:/sys/fs/cgroup/pids/test$ cat pids.current
2
dev@dev:/sys/fs/cgroup/pids/test$ cat cgroup.procs
3083

#subtest里面的數據如下:
dev@dev:/sys/fs/cgroup/pids/test$ cat subtest/pids.max
5
dev@dev:/sys/fs/cgroup/pids/test$ cat subtest/pids.current
1
dev@dev:/sys/fs/cgroup/pids/test$ cat subtest/cgroup.procs
3185
#--------------------------第一個shell窗口----------------------
#回到第一個窗口,隨便運行一個命令,由于test里面的pids.current已經等于pids.max了,
#所以創建新進程失敗,于是命令運行失敗,說明限制生效
dev@dev:/sys/fs/cgroup/pids/test$ ls
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: Resource temporarily unavailable
#--------------------------第二個shell窗口----------------------
#回到第二個窗口,隨便運行一個命令,雖然subtest里面的pids.max還大于pids.current,
#但由于其父cgroup “test”里面的pids.current已經等于pids.max了,
#所以創建新進程失敗,于是命令運行失敗,說明子cgroup中的進程數不僅受自己的pids.max的限制,還受祖先cgroup的限制
dev@dev:/sys/fs/cgroup/pids/test/subtest$ ls
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: Resource temporarily unavailable

pids.current > pids.max 的情況

并不是所有情況下都是 pids.max >= pids.current,在下面兩種情況下,會出現 pids.max < pids.current 的情況:

  • 設置 pids.max 時,將其值設置的比 pids.current 小
  • 將其他進程加入到當前 cgroup 有可能會導致 pids.current > pids.max
    • 因為 pids.max 只會在當前 cgroup 中的進程 fork、clone 的時候生效,將其他進程加入到當前 cgroup 時,不會檢測 pids.max,所以可能觸發這種情況

小結

作用:pids subsystem 用于限制 cgroups 下能夠創建的 task(進程和線程)數。

原理:在調用 fork 和 clone 時對比 subsystem 中配置的 pids.max 和 pids.current 值來判斷當前是否能夠繼續創建 task。

用法:配置 pids.max 防止容器消耗完 pid。

2. cpu

在 cgroup 里面,跟 CPU 相關的子系統有 cpusets、cpuacct 和 cpu。

  • 其中 cpuset 主要用于設置 CPU 的親和性,可以限制 cgroup 中的進程只能在指定的 CPU 上運行,或者不能在指定的 CPU 上運行,同時 cpuset 還能設置內存的親和性。設置親和性一般只在比較特殊的情況才用得著,所以這里不做介紹。

  • cpuacct 包含當前 cgroup 所使用的 CPU 的統計信息,信息量較少,有興趣可以去看看它的文檔,這里不做介紹。

本節只介紹 cpu 子系統,包括怎么限制 cgroup 的 CPU 使用上限及相對于其它 cgroup 的相對值。

創建子 cgroup

通用是創建子目錄即可。

#進入/sys/fs/cgroup/cpu并創建子cgroup
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu# cd /sys/fs/cgroup/cpu
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu# mkdir test
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu# cd test/
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu/test# ls
cgroup.clone_children  cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.procs           cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks

看起來文件比 memory subsystem 還是少一些。

cpu.cfs_period_us & cpu.cfs_quota_us:兩個文件配合起來設置 CPU 的使用上限,兩個文件的單位都是微秒(us)。

  • cfs_period_us:用來配置時間周期長度
    • 取值范圍為 1 毫秒(ms)到 1 秒(s)
  • cfs_quota_us:用來配置當前 cgroup 在設置的周期長度內所能使用的 CPU 時間數
    • 取值大于 1ms 即可
    • 默認值為 -1,表示不受 cpu 時間的限制。

cpu.shares 用來設置 CPU 的相對值(比例),并且是針對所有的 CPU(內核),默認值是 1024。

假如系統中有兩個 cgroup,分別是 A 和 B,A 的 shares 值是 1024,B 的 shares 值是 512,那么 A 將獲得 1024/(1204+512)=66% 的 CPU 資源,而 B 將獲得 33% 的 CPU 資源。

shares 有兩個特點:

  • 如果 A 不忙,沒有使用到 66% 的 CPU 時間,那么剩余的 CPU 時間將會被系統分配給 B,即 B 的 CPU 使用率可以超過 33%
  • 如果添加了一個新的 cgroup C,且它的 shares 值是 1024,那么 A 的限額變成了 1024/(1204+512+1024)=40%,B 的變成了 20%

從上面兩個特點可以看出:

  • 在閑的時候,shares 基本上不起作用,只有在 CPU 忙的時候起作用,這是一個優點。
  • 由于 shares 是一個絕對值,需要和其它 cgroup 的值進行比較才能得到自己的相對限額,而在一個部署很多容器的機器上,cgroup 的數量是變化的,所以這個限額也是變化的,自己設置了一個高的值,但別人可能設置了一個更高的值,所以這個功能沒法精確的控制 CPU 使用率。

cpu.stat 包含了下面三項統計結果:

  • nr_periods: 表示過去了多少個 cpu.cfs_period_us 里面配置的時間周期
  • nr_throttled: 在上面的這些周期中,有多少次是受到了限制(即 cgroup 中的進程在指定的時間周期中用光了它的配額)
  • throttled_time: cgroup 中的進程被限制使用 CPU 持續了多長時間(納秒)

原理

前面配置的參數都是 cfs_xxx,這里的 cfs 是 Completely Fair Scheduler 的縮寫。

CFS 是 Linux 內核中的調度器,它負責決定哪個進程在給定時間片內運行。CFS 使用 CFS 配額(cpu.cfs_quota_us)和 CFS 周期(cpu.cfs_period_us)來限制每個 cgroup 中的 CPU 使用。

CFS 的實現與 cgroups 協同工作,它負責追蹤每個 cgroup 中的進程消耗的 CPU 時間,并在每個調度周期結束時根據 cgroup 的 CPU 配額調整進程的運行時間。

如果一個 cgroup 中的進程在調度周期內超過了它的 CPU 配額,它將被調度器限制,從而實現了 CPU 的使用限制。

即:cgroups 中的 subsystem 負責提供配置,cfs 負責記錄進程使用的 cpu 時間,達到閾值后就從調度層面進行限制,避免該進程繼續使用 cpu。

演示

#繼續使用上面創建的子cgroup: test
#設置只能使用1個cpu的20%的時間
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 50000 > cpu.cfs_period_us"
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 10000 > cpu.cfs_quota_us"

#將當前bash加入到該cgroup
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ echo $$
5456
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ sudo sh -c "echo 5456 > cgroup.procs"

#在bash中啟動一個死循環來消耗cpu,正常情況下應該使用100%的cpu(即消耗一個內核)
dev@ubuntu:/sys/fs/cgroup/cpu,cpuacct/test$ while :; do echo test > /dev/null; done

#--------------------------重新打開一個shell窗口----------------------
#通過top命令可以看到5456的CPU使用率為20%左右,說明被限制住了
#不過這時系統的%us+%sy在10%左右,那是因為我測試的機器上cpu是雙核的,
#所以系統整體的cpu使用率為10%左右
dev@ubuntu:~$ top
Tasks: 139 total,   2 running, 137 sleeping,   0 stopped,   0 zombie
%Cpu(s):  5.6 us,  6.2 sy,  0.0 ni, 88.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   499984 total,    15472 free,    81488 used,   403024 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   383332 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 5456 dev       20   0   22640   5472   3524 R  20.3  1.1   0:04.62 bash

#這時可以看到被限制的統計結果
dev@ubuntu:~$ cat /sys/fs/cgroup/cpu,cpuacct/test/cpu.stat
nr_periods 1436
nr_throttled 1304
throttled_time 51542291833
# cfs_period_us 值為 10W
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu/test# cat cpu.cfs_period_us
100000
# 往 cfs_quota_us 寫入 20000,即限制只能使用20%cpu
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu/test# echo 20000 > cpu.cfs_quota_us

# 新開一個窗口,運行一個死循環
$ while : ; do : ; done &
[1] 519
# top 看一下 cpu 占用率,果然是100%了

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  519 lixd      25   5   13444   2912      0 R 100.0   0.0   0:05.66 zsh


# 回到第一個shell窗口,限制當前進程的cpu使用率
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu/test# echo 519 >> cgroup.procs

# 再切回第二個窗口,發現519進程的cpu已經降到20%了,說明限制生效了
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  519 lixd      25   5   13444   2912      0 R  20.0   0.0   0:31.86 zsh

# 查看被限制的統計結果
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/cpu/test# cat cpu.stat
nr_periods 2090
nr_throttled 2088
throttled_time 166752684900

小結

作用:cpu subsystem 用于限制 cgroups 下進程可以使用的 cpu 上限。

原理:cgroups 中的 subsystem 負責提供配置,cfs 負責記錄進程使用的 cpu 時間,達到閾值后就從調度層面進行限制,避免該進程繼續使用 cpu。

用法:

  • 1)限制為具體值:用 cfs_period_us & cfs_quota_us 兩個配置可以嚴格限制進程 cpu 使用量。
  • 2)按比例分配:用 shares 配置,可以使得多個 cgroups 之間按比例分配所有 cpu。

3. memory

memory subsystem 顧名思義,限制 cgroups 中進程的內存使用。

為什么需要內存控制

  • 站在一個普通開發者的角度,如果能控制一個或者一組進程所能使用的內存數,那么就算代碼有 bug,內存泄漏也不會對系統造成影響,因為可以設置內存使用量的上限,當到達這個值之后可以將進程重啟。
  • 站在一個系統管理者的角度,如果能限制每組進程所能使用的內存量,那么不管程序的質量如何,都能將它們對系統的影響降到最低,從而保證整個系統的穩定性。

內存控制能控制些什么?

  • 限 制 cgroup 中所有進程所能使用的物理內存總量
  • 限制 cgroup 中所有進程所能使用的物理內存+交換空間總量(CONFIG_MEMCG_SWAP): 一般在 server 上,不太會用到 swap 空間,所以不在這里介紹這部分內容。
  • 限制 cgroup 中所有進程所能使用的內核內存總量及其它一些內核資源(CONFIG_MEMCG_KMEM): 限制內核內存有什么用呢?其實限制內核內存就是限制當前 cgroup 所能使用的內核資源,比如進程的內核棧空間,socket 所占用的內存空間等,通過限制內核內存,當內存吃緊時,可以阻止當前 cgroup 繼續創建進程以及向內核申請分配更多的內核資源。由于這塊功能被使用的較少,本篇中也不對它做介紹。

創建子 cgroup

在 /sys/fs/cgroup/memory 下創建一個子目錄就算是創建了一個子 cgroup

root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory# cd /sys/fs/cgroup/memory
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory# mkdir test
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory# ls test/
cgroup.clone_children           memory.kmem.tcp.max_usage_in_bytes  memory.oom_control
cgroup.event_control            memory.kmem.tcp.usage_in_bytes      memory.pressure_level
cgroup.procs                    memory.kmem.usage_in_bytes          memory.soft_limit_in_bytes
memory.failcnt                  memory.limit_in_bytes               memory.stat
memory.force_empty              memory.max_usage_in_bytes           memory.swappiness
memory.kmem.failcnt             memory.memsw.failcnt                memory.usage_in_bytes
memory.kmem.limit_in_bytes      memory.memsw.limit_in_bytes         memory.use_hierarchy
memory.kmem.max_usage_in_bytes  memory.memsw.max_usage_in_bytes     notify_on_release
memory.kmem.tcp.failcnt         memory.memsw.usage_in_bytes         tasks
memory.kmem.tcp.limit_in_bytes  memory.move_charge_at_immigrate

從上面 ls 的輸出可以看出,除了每個 cgroup 都有的那幾個文件外,和 memory 相關的文件還不少,這里先做個大概介紹(kernel 相關的文件除外),后面會詳細介紹每個文件的作用:

 cgroup.event_control       #用于eventfd的接口
 memory.usage_in_bytes      #顯示當前已用的內存
 memory.limit_in_bytes      #設置/顯示當前限制的內存額度
 memory.failcnt             #顯示內存使用量達到限制值的次數
 memory.max_usage_in_bytes  #歷史內存最大使用量
 memory.soft_limit_in_bytes #設置/顯示當前限制的內存軟額度
 memory.stat                #顯示當前cgroup的內存使用情況
 memory.use_hierarchy       #設置/顯示是否將子cgroup的內存使用情況統計到當前cgroup里面
 memory.force_empty         #觸發系統立即盡可能的回收當前cgroup中可以回收的內存
 memory.pressure_level      #設置內存壓力的通知事件,配合cgroup.event_control一起使用
 memory.swappiness          #設置和顯示當前的swappiness
 memory.move_charge_at_immigrate #設置當進程移動到其他cgroup中時,它所占用的內存是否也隨著移動過去
 memory.oom_control         #設置/顯示oom controls相關的配置
 memory.numa_stat           #顯示numa相關的內存

添加進程

也是往 cgroup 中添加進程只要將進程號寫入 cgroup.procs 就可以了。

#重新打開一個shell窗口,避免相互影響
root@DESKTOP-9K4GB6E:~# cd /sys/fs/cgroup/memory/test/
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo $$ >> cgroup.procs
#運行top命令,這樣這個cgroup消耗的內存會多點,便于觀察
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# top
# 后續操作不再在這個窗口進行,避免在這個bash中運行進程影響cgropu里面的進程數及相關統計

設置限額

設置限額很簡單,將閾值寫入 memory.limit_in_bytes 文件就可以了,例如:

  • echo 1M > memory.limit_in_bytes:限制只能用 1M 內存
  • echo -1 > memory.limit_in_bytes:-1 則是不限制
#回到第一個shell窗口
#開始設置之前,看看當前使用的內存數量,這里的單位是字節
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.usage_in_bytes
2379776
#設置1M的限額
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 1M > memory.limit_in_bytes
#設置完之后記得要查看一下這個文件,因為內核要考慮頁對齊, 所以生效的數量不一定完全等于設置的數量
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.usage_in_bytes
950272
#如果不再需要限制這個cgroup,寫-1到文件memory.limit_in_bytes即可
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo -1 > memory.limit_in_bytes
#這時可以看到limit被設置成了一個很大的數字
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.limit_in_bytes
9223372036854771712

如果設置的限額比當前已經使用的內存少呢?

root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# free -h
              total        used        free      shared  buff/cache   available
Mem:          7.7Gi       253Mi       7.4Gi       0.0Ki        95Mi       7.3Gi
Swap:         2.0Gi       0.0Ki       2.0Gi
# 此時用了 1232K
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.usage_in_bytes
1232896
# 限制成500K
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 500k > memory.limit_in_bytes
# 再次查看發現現在只用了401K
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.usage_in_bytes
401408
# 發現swap多了1M,說明另外的數據被轉移到swap上了
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# free -h
              total        used        free      shared  buff/cache   available
Mem:          7.7Gi       254Mi       7.4Gi       0.0Ki        94Mi       7.3Gi
Swap:         2.0Gi       1.0Mi       2.0Gi
#這個時候再來看failcnt,發現有381次之多(隔幾秒再看這個文件,發現次數在增長)
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.failcnt
381
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.failcnt
385

#再看看memory.stat(這里只顯示部分內容),發現物理內存用了400K,
#但有很多pgmajfault以及pgpgin和pgpgout,說明發生了很多的swap in和swap out
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.stat
swap 946176 # 946K 差不多剛好是內存中少的量
pgpgin 30492
pgpgout 30443
pgfault 23859
pgmajfault 12507

從上面的結果可以看出,當物理內存不夠時,就會觸發 memory.failcnt 里面的數量加 1,但進程不會被 kill 掉,那是因為內核會嘗試將物理內存中的數據移動到 swap 空間中,從而讓內存分配成功。

如果設置的限額過小,就算 swap out 部分內存后還是不夠會怎么樣?

#--------------------------第一個shell窗口----------------------
# 限制到100k
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 100K > memory.limit_in_bytes

#--------------------------第二個shell窗口----------------------
# 嘗試執行 top 發現剛運行就被Kill了
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# top
Killed

從上面的這些測試可以看出,一旦設置了內存限制,將立即生效,并且當物理內存使用量達到 limit 的時候,memory.failcnt 的內容會加 1,但這時進程不一定就會

被 kill 掉,內核會盡量將物理內存中的數據移到 swap 空間上去,如果實在是沒辦法移動了(設置的 limit 過小,或者 swap 空間不足),默認情況下,就會 kill 掉 cgroup 里面繼續申請內存的進程。

行為控制

通過修改memory.oom_control文件,可以控制 subsystem 在物理內存達到上限時的行為。文件中包含以下 3 個參數:

  • oom_kill_disable:是否啟用 oom kill
    • 0:關閉
    • 1:開啟
  • under_oom:表示當前是否已經進入 oom 狀態,也即是否有進程被暫停了。
  • oom_kill:oom 后是否執行 kill
    • 1:啟動,oom 后直接 kill 掉對應進程
    • 2:關閉:當內核無法給進程分配足夠的內存時,將會暫停該進程直到有空余的內存之后再繼續運行。同時會更新 under_oom 狀態
    • 注意:root cgroup 的 oom killer 是不能被禁用的

為了演示 OOM-killer 的功能,創建了下面這樣一個程序,用來向系統申請內存,它會每秒消耗 1M 的內存。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MB (1024 * 1024)

int main(int argc, char *argv[])
{
    char *p;
    int i = 0;
    while(1) {
        p = (char *)malloc(MB);
        memset(p, 0, MB);
        printf("%dM memory allocated\n", ++i);
        sleep(1);
    }

    return 0;
}

保存上面的程序到文件~/mem-allocate.c,然后編譯并測試

#--------------------------第一個shell窗口----------------------
#編譯上面的文件
dev@dev:/sys/fs/cgroup/memory/test$ gcc ~/mem-allocate.c -o ~/mem-allocate
#設置內存限額為5M
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 5M > memory.limit_in_bytes"
#將當前bash加入到test中,這樣這個bash創建的所有進程都會自動加入到test中
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo $$ >> cgroup.procs"
#默認情況下,memory.oom_control的值為0,即默認啟用oom killer
dev@dev:/sys/fs/cgroup/memory/test$ cat memory.oom_control
oom_kill_disable 0
under_oom 0
#為了避免受swap空間的影響,設置swappiness為0來禁止當前cgroup使用swap
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 0 > memory.swappiness"
#當分配第5M內存時,由于總內存量超過了5M,所以進程被kill了
dev@dev:/sys/fs/cgroup/memory/test$ ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
Killed

#設置oom_control為1,這樣內存達到限額的時候會暫停
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 1 >> memory.oom_control"
#跟預期的一樣,程序被暫停了
dev@dev:/sys/fs/cgroup/memory/test$ ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated

#--------------------------第二個shell窗口----------------------
#再打開一個窗口
dev@dev:~$ cd /sys/fs/cgroup/memory/test/
#這時候可以看到memory.oom_control里面under_oom的值為1,表示當前已經oom了
dev@dev:/sys/fs/cgroup/memory/test$ cat memory.oom_control
oom_kill_disable 1
under_oom 1
#修改test的額度為7M
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 7M > memory.limit_in_bytes"

#--------------------------第一個shell窗口----------------------
#再回到第一個窗口,會發現進程mem-allocate繼續執行了兩步,然后暫停在6M那里了
dev@dev:/sys/fs/cgroup/memory/test$ ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated

# 創建上面的文件并編譯
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# vim ~/mem-allocate.c
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# gcc ~/mem-allocate.c -o ~/mem-allocate
# 限制5M的上限
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 5M > memory.limit_in_bytes
#將當前bash加入到test中,這樣這個bash創建的所有進程都會自動加入到test中
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo $$ >> cgroup.procs
#默認情況下,會啟用oom killer
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.oom_control
oom_kill_disable 0
under_oom 0
oom_kill 1
#為了避免受swap空間的影響,設置swappiness為0來禁止當前cgroup使用swap
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 0 > memory.swappiness
#當分配第5M內存時,由于總內存量超過了5M,所以進程被kill了
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
Killed
#設置oom_control為1,這樣內存達到限額的時候會暫停
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 1 >> memory.oom_control
#跟預期的一樣,程序被暫停了
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated

#--------------------------第二個shell窗口----------------------
#再打開一個窗口
dev@dev:~$ cd /sys/fs/cgroup/memory/test/
#這時候可以看到memory.oom_control里面under_oom的值為1,表示當前已經oom了
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# cat memory.oom_control
oom_kill_disable 1
under_oom 1
oom_kill 2
#修改test的額度為7M
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# echo 7M > memory.limit_in_bytes

# 切換會第一個窗口,發送程序又跑了兩步,停在了6M
root@DESKTOP-9K4GB6E:/sys/fs/cgroup/memory/test# ~/mem-allocate
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated

其他

進程遷移(migration)

當一個進程從一個 cgroup 移動到另一個 cgroup 時,默認情況下,該進程已經占用的內存還是統計在原來的 cgroup 里面,不會占用新 cgroup 的配額,但新分配的內存會統計到新的 cgroup 中(包括 swap out 到交換空間后再 swap in 到物理內存中的部分)。

我們可以通過設置 memory.move_charge_at_immigrate 讓進程所占用的內存隨著進程的遷移一起遷移到新的 cgroup 中。

enable: echo 1 > memory.move_charge_at_immigrate
disable:echo 0 > memory.move_charge_at_immigrate

注意: 就算設置為 1,但如果不是 thread group 的 leader,這個 task 占用的內存也不能被遷移過去。

換句話說,如果以線程為單位進行遷移,必須是進程的第一個線程,如果以進程為單位進行遷移,就沒有這個問題。

當 memory.move_charge_at_immigrate 被設置成 1 之后,進程占用的內存將會被統計到目的 cgroup 中,如果目的 cgroup 沒有足夠的內存,系統將嘗試回收目的 cgroup 的部分內存(和系統內存緊張時的機制一樣,刪除不常用的 file backed 的內存或者 swap out 到交換空間上,請參考Linux 內存管理),如果回收不成功,那么進程遷移將失敗。

注意:遷移內存占用數據是比較耗時的操作。

移除 cgroup

當 memory.move_charge_at_immigrate 為 0 時,就算當前 cgroup 中里面的進程都已經移動到其它 cgropu 中去了,由于進程已經占用的內存沒有被統計過去,當前 cgroup 有可能還占用很多內存,當移除該 cgroup 時,占用的內存需要統計到誰頭上呢?

答案是依賴 memory.use_hierarchy 的值,

  • 如果該值為 0,將會統計到 root cgroup 里;
  • 如果值為 1,將統計到它的父 cgroup 里面。

force_empty

當向 memory.force_empty 文件寫入 0 時(echo 0 > memory.force_empty),將會立即觸發系統盡可能的回收該 cgroup 占用的內存。該功能主要使用場景是移除 cgroup 前(cgroup 中沒有進程),先執行該命令,可以盡可能的回收該 cgropu 占用的內存,這樣遷移內存的占用數據到父 cgroup 或者 root cgroup 時會快些。

memory.swappiness

該文件的值默認和全局的 swappiness(/proc/sys/vm/swappiness)一樣,修改該文件只對當前 cgroup 生效,其功能和全局的 swappiness 一樣,請參考Linux 交換空間中關于 swappiness 的介紹。

注意:有一點和全局的 swappiness 不同,那就是如果這個文件被設置成 0,就算系統配置的有交換空間,當前 cgroup 也不會使用交換空間。

memory.use_hierarchy

該文件內容為 0 時,表示不使用繼承,即父子 cgroup 之間沒有關系;當該文件內容為 1 時,子 cgroup 所占用的內存會統計到所有祖先 cgroup 中。

如果該文件內容為 1,當一個 cgroup 內存吃緊時,會觸發系統回收它以及它所有子孫 cgroup 的內存。

注意: 當該 cgroup 下面有子 cgroup 或者父 cgroup 已經將該文件設置成了 1,那么當前 cgroup 中的該文件就不能被修改。

#當前cgroup和父cgroup里都是1
dev@dev:/sys/fs/cgroup/memory/test$ cat memory.use_hierarchy
1
dev@dev:/sys/fs/cgroup/memory/test$ cat ../memory.use_hierarchy
1

#由于父cgroup里面的值為1,所以修改當前cgroup的值失敗
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 0 > ./memory.use_hierarchy"
sh: echo: I/O error

#由于父cgroup里面有子cgroup(至少有當前cgroup這么一個子cgroup),
#修改父cgroup里面的值也失敗
dev@dev:/sys/fs/cgroup/memory/test$ sudo sh -c "echo 0 > ../memory.use_hierarchy"
sh: echo: I/O error

memory.soft_limit_in_bytes

有了 hard limit(memory.limit_in_bytes),為什么還要 soft limit 呢?hard limit 是一個硬性標準,絕對不能超過這個值。

而 soft limit 可以被超越,既然能被超越,要這個配置還有啥用?先看看它的特點

  • 1)當系統內存充裕時,soft limit 不起任何作用
  • 2)當系統內存吃緊時,系統會盡量的將 cgroup 的內存限制在 soft limit 值之下(內核會盡量,但不 100% 保證)

從它的特點可以看出,它的作用主要發生在系統內存吃緊時,如果沒有 soft limit,那么所有的 cgroup 一起競爭內存資源,占用內存多的 cgroup 不會讓著內存占用少的 cgroup,這樣就會出現某些 cgroup 內存饑餓的情況。如果配置了 soft limit,那么當系統內存吃緊時,系統會讓超過 soft limit 的 cgroup 釋放出超過 soft limit 的那部分內存(有可能更多),這樣其它 cgroup 就有了更多的機會分配到內存。

從上面的分析看出,這其實是系統內存不足時的一種妥協機制,給次等重要的進程設置 soft limit,當系統內存吃緊時,把機會讓給其它重要的進程。

注意: 當系統內存吃緊且 cgroup 達到 soft limit 時,系統為了把當前 cgroup 的內存使用量控制在 soft limit 下,在收到當前 cgroup 新的內存分配請求時,就會觸發回收內存操作,所以一旦到達這個狀態,就會頻繁的觸發對當前 cgroup 的內存回收操作,會嚴重影響當前 cgroup 的性能。

memory.pressure_level

這個文件主要用來監控當前 cgroup 的內存壓力,當內存壓力大時(即已使用內存快達到設置的限額),在分配內存之前需要先回收部分內存,從而影響內存分配速度,影響性能,而通過監控當前 cgroup 的內存壓力,可以在有壓力的時候采取一定的行動來改善當前 cgroup 的性能,比如關閉當前 cgroup 中不重要的服務等。目前有三種壓力水平:

  • low

    • 意味著系統在開始為當前 cgroup 分配內存之前,需要先回收內存中的數據了,這時候回收的是在磁盤上有對應文件的內存數據。
  • medium

    • 意味著系統已經開始頻繁為當前 cgroup 使用交換空間了。
  • critical

    • 快撐不住了,系統隨時有可能 kill 掉 cgroup 中的進程。

如何配置相關的監聽事件呢?和 memory.oom_control 類似,大概步驟如下:

  1. 利用函數 eventfd(2) 創建一個 event_fd
  2. 打開文件 memory.pressure_level,得到 pressure_level_fd
  3. 往 cgroup.event_control 中寫入這么一串:<event_fd> <pressure_level_fd> <level>
  4. 然后通過讀 event_fd 得到通知

注意: 多個 level 可能要創建多個 event_fd,好像沒有辦法共用一個

Memory thresholds

我們可以通過 cgroup 的事件通知機制來實現對內存的監控,當內存使用量穿過(變得高于或者低于)我們設置的值時,就會收到通知。使用方法和 memory.oom_control 類似,大概步驟如下:

  1. 利用函數 eventfd(2) 創建一個 event_fd
  2. 打開文件 memory.usage_in_bytes,得到 usage_in_bytes_fd
  3. 往 cgroup.event_control 中寫入這么一串:<event_fd> <usage_in_bytes_fd> <threshold>
  4. 然后通過讀 event_fd 得到通知

stat file

這個文件包含的統計項比較細,需要一些內核的內存管理知識才能看懂,這里就不介紹了(怕說錯)。詳細信息可以參考 Memory Resource Controller中的“5.2 stat file”。這里有幾個需要注意的地方:

  • 里面 total 開頭的統計項包含了子 cgroup 的數據(前提條件是 memory.use_hierarchy 等于 1)。
  • 里面的 'rss + file_mapped" 才約等于是我們常說的 RSS(ps aux 命令看到的 RSS)
  • 文件(動態庫和可執行文件)及共享內存可以在多個進程之間共享,不過它們只會統計到他們的 owner cgroup 中的 file_mapped 去。(不確定是怎么定義 owner 的,但如果看到當前 cgroup 的 file_mapped 值很小,說明共享的數據沒有算到它頭上,而是其它的 cgroup)

小結

作用:限制 cgroups 中的進程占用的內存上限

用法:

  • 1)memory.limit_in_bytes 配置進程可以使用的內存上限(hard limit),當超過該閾值時,一般是嘗試使用 swap,如果不行則直接 kill 掉。
  • 2)memory.soft_limit_in_bytes 配置進程可以使用的內存上行(soft limit),當系統內存不足時,cgroups 會優先將使用量超過 soft limit 的進程進行內存回收,騰出內存。
  • 3)memory.oom_control 參數配置內存使用量到達閾值時內核的處理行為,默認為 oom_kill。

原理:當進程使用內存超過memory.limit_in_bytes 之后,系統會根據 memory.oom_control 配置的行為進行處理,一般是嘗試使用 swap,如果不行則直接 kill 掉。

本節沒有介紹 swap 和 kernel 相關的內容,不過在實際使用過程中一定要留意 swap 空間,如果系統使用了交換空間,那么設置限額時一定要注意一點,那就是當 cgroup 的物理空間不夠時,內核會將不常用的內存 swap out 到交換空間上,從而導致一直不觸發 oom killer,而是不停的 swap out/in,導致 cgroup 中的進程運行速度很慢。

如果一定要用交換空間,最好的辦法是限制 swap+物理內存 的額度,雖然我們在這篇中沒有介紹這部分內容,但其使用方法和限制物理內存是一樣的,只是換做寫文件 memory.memsw.limit_in_bytes 罷了。

4. 小結

本文主要簡單介紹了 pid、cpu、memory 這三個 subsystem 的作用和基本使用,具體如下:

subsystem 功能 用法 原理 備注
pid 限制 cgroups 中進程使用的 pid 數 配置 subsystem 中的 pids.max 即可 當 cgroups 中的進程調用 fork 或者 clone 系統調用時會判斷,subsystem 中配置的 pids.max 和當前 pids.current 的值,來確定是否能夠創建新的進程(或線程) linux 中的 pid 是有限的,通過該 subsystem 可以有效防止 fork 炸彈之類的惡意進程
cpu 限制 cgroups 中進程使用的 cpu 上限 1)限制為具體值:用 cfs_period_us & cfs_quota_us 兩個配置可以嚴格限制進程 cpu 使用量。 2)按比例分配:用 shares 配置,可以使得多個 cgroups 之間按比例分配所有 cpu。 subsystem 負責提供配置,cfs 負責記錄進程使用的 cpu 時間,達到閾值后就從調度層面進行限制,避免該進程繼續使用 cpu。 一般使用 cfs_period_us & cfs_quota_us 方式限制具體值用得比較多。
memory 限制 cgroups 中進程使用的 memory 上限 1)memory.limit_in_bytes 配置進程可以使用的內存上限(hard limit),當超過該閾值時,一般是嘗試使用 swap,如果不行則直接 kill 掉。 2)memory.soft_limit_in_bytes 配置進程可以使用的內存上行(soft limit),當系統內存不足時,cgroups 會優先將使用量超過 soft limit 的進程進行內存回收,騰出內存。 3)memory.oom_control 參數配置內存使用量到達閾值時內核的處理行為,默認為 oom_kill。 當進程使用內存超過memory.limit_in_bytes 之后,系統會根據 memory.oom_control 配置的行為進行處理,一般是嘗試使用 swap,如果不行則直接 kill 掉。 如果系統使用了交換空間,那么設置限額時一定要注意一點,那就是當 cgroup 的物理空間不夠時,內核會將不常用的內存 swap out 到交換空間上,從而導致一直不觸發 oom killer,而是不停的 swap out/in,導致 cgroup 中的進程運行速度很慢。

如果你對云原生技術充滿好奇,想要深入了解更多相關的文章和資訊,歡迎關注微信公眾號。

搜索公眾號【探索云原生】即可訂閱


5. 參考

cgroups(7) — Linux manual page

美團技術團隊---Linux 資源管理之 cgroups 簡介

Red Hat---資源管理指南

總結

以上是生活随笔為你收集整理的深入剖析 Linux Cgroups 子系统:资源精细管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久成人一区二区 | www.天天射 | 成人超碰在线 | 草久久精品 | 天海翼一区二区三区免费 | a资源在线 | 国产精品久久久久永久免费观看 | 中文字幕 国产精品 | 欧美日韩国产二区三区 | av在线色 | www.av免费 | 超碰999| 婷婷六月综合亚洲 | 四月婷婷在线观看 | 国产精品视频你懂的 | 色婷婷激情电影 | 国产精品99爱 | 成人国产网址 | 在线播放亚洲 | 99中文字幕| 一区二区三区在线免费 | 在线av资源 | 91av视频| 国产97在线视频 | 91亚洲综合 | 国产黄色一级片在线 | 国产精品尤物 | 玖玖在线看 | 国内成人av | 国产精品第一页在线 | 九色精品免费永久在线 | 91大神dom调教在线观看 | 亚洲性视频 | adc在线观看 | 97精品国自产拍在线观看 | 亚洲国产一二三 | 丁香电影小说免费视频观看 | 六月丁香社区 | 最新色站 | 激情综合亚洲 | 国色天香永久免费 | 98超碰人人| 国产精品一区二区在线观看免费 | 99热精品免费观看 | 久久激情片 | 天天干天天拍天天操 | 最近更新好看的中文字幕 | 亚洲国产成人精品在线观看 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 午夜av激情 | 久久久久国产视频 | 亚洲资源在线 | 91精品视频网站 | 最近日本mv字幕免费观看 | 香蕉视频在线看 | 三级黄色理论片 | 国产在线日韩 | 国产午夜在线 | 国产精品久久精品 | 狠狠狠色丁香综合久久天下网 | 久久国产精品小视频 | 91污污| 一级成人网 | 精一区二区 | 免费大片av| www.天天综合| 日韩精品一区二 | 伊人丁香 | 深爱婷婷激情 | 激情在线免费视频 | www最近高清中文国语在线观看 | 亚洲欧美日韩精品久久久 | 欧美a视频 | 欧美日韩精品在线视频 | 最新中文字幕在线资源 | 91成人免费视频 | 国产成人精品综合久久久久99 | 国产麻豆精品在线观看 | 久久久久高清毛片一级 | 日韩成人免费在线电影 | 国产精品一区二区三区电影 | 久草免费在线视频观看 | 91人人人| 丝袜美女视频网站 | 91网在线 | 久久精品这里热有精品 | 永久免费在线 | 久久久精品网站 | 欧美日韩国产一二三区 | 色婷婷综合视频在线观看 | 国产日产精品久久久久快鸭 | 久久精品这里精品 | 在线免费视频 你懂得 | 人人爱在线视频 | 四虎在线免费观看视频 | 久久精品一区二区三区视频 | 久久人人爽人人爽人人片av免费 | 欧美日韩高清一区二区三区 | 一二三区高清 | 9色在线视频 | 免费三级av | 碰超在线 | 国产视频一区二区在线播放 | aav在线 | 精品国产1区二区 | 久草在线手机观看 | 欧美经典久久 | 免费观看黄色12片一级视频 | 777久久久 | 欧美色黄 | 欧美日韩高清一区 | 国产精品va在线观看入 | 视频成人免费 | 日韩免费电影网 | 国产精品麻豆99久久久久久 | 久草在线视频资源 | 国产精品成人久久久久久久 | 99一级片 | 国产精品午夜久久 | 久久国产精品99久久久久久进口 | 三级黄色在线观看 | 国产又黄又爽又猛视频日本 | 黄色大全在线观看 | 色丁香婷婷 | 久久久久久久久电影 | 国产精品剧情 | 99免费在线播放99久久免费 | 国产一线二线三线性视频 | 亚洲理论在线观看 | 亚洲精品成人免费 | 亚洲精品999 | 三级黄色网络 | 亚洲三级影院 | 欧美日韩二区在线 | 免费在线观看成年人视频 | 久久精品综合 | 97视频免费播放 | av电影亚洲 | 97精品在线视频 | 亚洲欧美国产视频 | 欧美日韩亚洲精品在线 | 99久久日韩精品视频免费在线观看 | 免费麻豆 | 97免费视频在线 | 人人澡人人舔 | 成 人 免费 黄 色 视频 | 欧美日韩在线观看一区二区三区 | 久久精品福利视频 | 99婷婷狠狠成为人免费视频 | 啪啪精品 | 国产麻豆精品在线观看 | 欧美黑人猛交 | 日韩免费不卡av | 丝袜一区在线 | 成人av免费网站 | 中文在线免费视频 | 激情综合网在线观看 | 国产成人av网址 | 国产黄色精品 | 国产在线91在线电影 | 欧美日韩大片在线观看 | 91精品国产91 | 久久国产品 | 日韩免费不卡av | 在线看片成人 | 91成人短视频在线观看 | 9797在线看片亚洲精品 | 亚洲一二三久久 | 黄色a级片在线观看 | 综合色中色 | 国产一级电影在线 | 亚洲视频在线视频 | 国产精品久久久久久久7电影 | 超碰人人超 | 亚洲春色综合另类校园电影 | 在线免费av电影 | 日韩色在线观看 | 人人舔人人干 | 超碰国产在线 | 亚洲精品在线观看中文字幕 | 天天在线免费视频 | 色就色,综合激情 | 亚洲综合五月 | 久久免费看av | 欧美日韩视频在线观看免费 | 日韩字幕 | 久精品视频免费观看2 | 国产一级免费观看 | 国产无套视频 | 色干综合 | 91视频电影| 二区视频在线 | 国产剧情在线一区 | 国产成人99久久亚洲综合精品 | 69av国产 | 久久成人黄色 | 国产精品久久久久av福利动漫 | 国产成人亚洲在线电影 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 超碰在线人人艹 | 亚洲精品美女久久17c | 亚洲精品合集 | 久草资源在线观看 | 色综合久久久久 | 97精品国产一二三产区 | 又粗又长又大又爽又黄少妇毛片 | 特黄一级毛片 | 国产福利91精品一区 | 狠狠精品 | av免费网 | 欧美日韩在线看 | 久草在线中文视频 | 亚洲免费在线观看视频 | 日韩免费电影一区二区三区 | 国产精品免费高清 | av黄免费看 | 福利一区二区三区四区 | 在线观看一区二区精品 | 亚洲欧美在线观看视频 | 亚洲人成在线电影 | 亚洲综合涩 | 92中文资源在线 | 免费在线成人av电影 | 亚洲黄色小说网 | 精品国产欧美一区二区三区不卡 | 黄色av一级片 | 国产视频一区二区在线观看 | av免费线看 | 狠狠躁夜夜a产精品视频 | 亚洲a色 | 最新av在线免费观看 | 视频在线一区 | 国产另类av| 欧美日韩精品在线观看 | 久久国产精品影视 | 一二区av | 欧美日韩国产一区二 | 欧美aaaxxxx做受视频 | 日韩在线短视频 | 欧美老人xxxx18 | 国内成人精品视频 | 亚洲男男gaygay无套同网址 | 九九热免费在线观看 | 久久黄色小说视频 | 伊人永久在线 | 国产黄大片 | 三级av中文字幕 | 中文字幕最新精品 | 2023av| 色综合久久88色综合天天免费 | 国产高清中文字幕 | 天天操天天操天天操天天操天天操天天操 | 欧美性色综合网 | 国产精品美女www爽爽爽视频 | 999视频网站 | av片中文字幕 | 久久精品99精品国产香蕉 | 欧美日韩免费看 | 99久久精品费精品 | 日韩精品你懂的 | 欧美精品久久久久久久久久白贞 | 99热在线看| 日本最新中文字幕 | 婷婷在线免费 | 免费观看一区二区 | 福利视频网站 | 人人舔人人爽 | 97av在线 | 韩国视频一区二区三区 | 国产成人精品女人久久久 | 欧美日韩国产在线 | 青青河边草免费直播 | 国产午夜精品av一区二区 | 伊人射 | 精品福利在线视频 | 在线观看亚洲国产 | 国产精品99久久免费黑人 | 四虎成人精品在永久免费 | 天天天天色射综合 | 成人丁香花 | 免费亚洲精品 | 99精品国产一区二区三区麻豆 | 97国产大学生情侣酒店的特点 | 欧美一级久久 | 免费在线观看一区二区三区 | 午夜成人免费电影 | 欧美成人黄色片 | 亚洲精品乱码久久久久久蜜桃不爽 | 草久热 | 五月婷婷香蕉 | 天天干天天操 | 亚洲一区美女视频在线观看免费 | 色婷婷骚婷婷 | 免费三级av | 91人人插| 91精品无人成人www | 久久精美视频 | 日韩在线三级 | 色欧美成人精品a∨在线观看 | 91精品在线播放 | 久久综合色播五月 | 亚洲更新最快 | 玖玖视频免费在线 | 日本一区二区三区免费看 | 91福利区一区二区三区 | 久久久99精品免费观看app | 国产精品国产精品 | 丁香花在线视频观看免费 | 午夜电影一区 | 成人免费看电影 | 久草在线这里只有精品 | 久久精品国产精品亚洲 | 中文字幕亚洲综合久久五月天色无吗'' | 午夜久久久久久久 | 国产+日韩欧美 | 欧美一级裸体视频 | 成人午夜电影在线播放 | 免费观看特级毛片 | 午夜av影院 | 黄色三几片 | 日韩中文字幕免费电影 | 国产精品久久久99 | 日韩av电影中文字幕 | 久久这里精品视频 | 中文字幕高清视频 | 日韩在线观看你懂得 | 麻豆精品传媒视频 | 99精品在这里 | 婷婷在线免费观看 | 视频一区在线播放 | 亚洲狠狠丁香婷婷综合久久久 | 国产精品video爽爽爽爽 | 久久精品国产免费看久久精品 | 国产福利在线免费 | 午夜精品麻豆 | 亚洲中字幕 | 最新日韩在线观看视频 | 玖玖在线资源 | 超碰在线最新地址 | 狠狠躁夜夜躁人人爽超碰91 | 天天操人人要 | 国产精品 999 | 美女视频黄频 | 韩日在线一区 | 精品久久久久久国产偷窥 | 超碰公开在线 | 欧美特一级 | 99产精品成人啪免费网站 | 奇米导航| 国产二区视频在线观看 | 久久97久久 | 日日爽| 久久久91精品国产一区二区三区 | 狠狠色香婷婷久久亚洲精品 | 免费能看的黄色片 | 伊人看片 | 99精品国产视频 | 亚洲日本国产精品 | 欧美日韩国产精品一区二区 | 久久艹在线 | 欧美日韩高清国产 | 四虎国产精 | 婷婷丁香七月 | 日韩aa视频| 免费亚洲精品视频 | 成年人免费av网站 | 91av片| www.xxx.性狂虐 | 狠狠色丁香 | 黄色在线免费观看网站 | 免费一级片观看 | 亚洲成年人在线播放 | 免费在线观看国产黄 | 波多野结衣资源 | 99精品网站 | 伊人电影在线观看 | 一区二区三区免费在线观看 | 国产女人18毛片水真多18精品 | 国产精品久久久久久超碰 | 久久精品小视频 | 在线观看91av| 成av在线 | 成人aaa毛片 | 日韩在线精品视频 | 日日干日日操 | 欧美日韩伦理在线 | 精品三级av | 国内成人精品2018免费看 | 国产黄色理论片 | 成人中文字幕在线 | 视频在线播放国产 | 中文字幕黄网 | 99久久综合精品五月天 | 国产美女精品视频免费观看 | 综合国产在线观看 | 日本中出在线观看 | 久久精品国产精品亚洲精品 | 亚洲三级在线 | 欧美精品一区二区免费 | 国产综合片 | 欧美日韩精品在线播放 | 亚洲一区二区精品视频 | 久久精品福利 | 午夜视频日本 | 亚洲精品午夜久久久 | 久久久精品一区二区 | 麻豆va一区二区三区久久浪 | 成年人电影免费看 | www国产亚洲精品久久网站 | 国产精品久久亚洲 | 超碰免费97 | 成人91免费视频 | 日日操夜 | 日本成人黄色片 | 91精品在线播放 | 国产高清99 | 黄色三级在线看 | 午夜 在线| 国产在线精 | av成人免费在线 | 日韩av快播电影网 | 久久国产乱 | 欧美视屏一区二区 | av免费高清观看 | 天天在线视频色 | 日p视频在线观看 | 一区二区伦理 | 日韩免费在线 | 国产精品乱看 | 国产美女精品视频 | 久久精品国产免费看久久精品 | 色婷婷亚洲婷婷 | 黄色特级毛片 | 亚洲成人av电影在线 | 色夜影院 | 亚洲国产精品电影在线观看 | 天堂va在线观看 | 国产精品成人免费精品自在线观看 | 91日韩在线 | 国内成人综合 | 久久久五月天 | 黄色1级大片 | 日p视频在线观看 | 免费在线激情电影 | 九九热.com| av电影在线观看完整版一区二区 | 欧美一级特黄高清视频 | av在线不卡观看 | 色婷婷成人网 | 99精品久久只有精品 | 人人视频网站 | 国产精品第52页 | 国产在线一线 | 91精品国产入口 | 激情欧美丁香 | 日韩一区二区在线免费观看 | 免费在线成人 | 中文字幕永久在线 | 国产成本人视频在线观看 | 免费在线色电影 | 狠狠干在线 | 99精品视频观看 | 91精品国产91久久久久久三级 | 欧美资源 | 国产永久免费高清在线观看视频 | 精品久久久成人 | 国产精品久久久免费 | 亚洲视频久久久久 | 最新动作电影 | 久久久久久久久久久久国产精品 | 国产高清在线一区 | 中文字幕亚洲欧美 | 91成人在线看 | 亚洲第一久久久 | 精品国产黄色片 | 精品a视频 | 国产剧情一区二区 | 国产亚洲激情视频在线 | 久久这里只有精品视频首页 | 中文字幕在线视频一区二区 | 欧美伦理电影一区二区 | 日日摸日日爽 | 91丨九色丨蝌蚪丰满 | 国产亚洲在线观看 | 人人添人人澡 | www.色五月| 精品久久精品久久 | 日韩中文字幕在线看 | 亚洲国产免费看 | 综合在线观看 | 久久免费观看少妇a级毛片 久久久久成人免费 | 五月婷婷精品 | 久久av一区二区三区亚洲 | 超碰免费观看 | 国产91av视频在线观看 | 欧美视频18 | 在线观看av中文字幕 | 狠狠狠色丁香婷婷综合久久五月 | 国产精品免费久久久久久 | 91亚色视频| 天堂av在线网址 | 婷婷中文字幕综合 | 国产精品1区2区3区 久久免费视频7 | 五月天.com| 欧美日韩在线观看一区二区 | 国产一区二区久久久久 | 亚洲视频六区 | 91精品国自产在线观看欧美 | 99视频在线精品免费观看2 | 天天操天天综合网 | 999在线精品| 国产丝袜高跟 | 国产视| 国产精品久久中文字幕 | 亚洲最大色| 伊人久操 | 在线观看免费高清视频大全追剧 | 黄色软件在线观看 | 天天操天天干天天爽 | 日韩色视频在线观看 | 日韩不卡高清视频 | 日韩中字在线观看 | 欧美国产日韩一区 | 九九热只有这里有精品 | 狠狠干天天操 | 精品福利国产 | 91网页版在线观看 | 亚洲日本精品 | 免费观看9x视频网站在线观看 | 欧美 日韩 视频 | 天天操综合网站 | 久久精品com | 精品国产自在精品国产精野外直播 | 日本动漫做毛片一区二区 | 深爱激情综合 | 婷婷 中文字幕 | 亚洲一区二区天堂 | 亚洲成av人片一区二区梦乃 | 亚洲激情 | 99婷婷狠狠成为人免费视频 | www..com黄色片 | 在线观看播放av | 亚洲国产一区二区精品专区 | 国产专区免费 | 亚洲精色| 精品视频免费久久久看 | 懂色av一区二区三区蜜臀 | 成人国产网站 | 中文字幕影片免费在线观看 | 天天干天天摸 | 黄色视屏免费在线观看 | 久久综合五月天婷婷伊人 | 久久精品一区二区三区视频 | 啪啪小视频网站 | 激情五月在线视频 | 日本三级中文字幕在线观看 | 中文字幕高清在线播放 | 免费电影一区二区三区 | 五月婷久久| 中文网丁香综合网 | 在线不卡中文字幕播放 | 亚洲综合一区二区精品导航 | 在线成人性视频 | 欧美永久视频 | 黄色毛片在线看 | 精品九九久久 | 一区二区精品在线视频 | 在线观看完整版免费 | 欧美另类亚洲 | 最近最新中文字幕 | 欧美天堂久久 | 国产视频2区 | 亚洲永久免费av | 日韩欧美不卡 | 日韩免费看 | 波多野结衣视频在线 | 国产精品99久久久久 | 国产中文在线字幕 | av不卡中文 | 日日夜夜噜 | a在线免费 | 国产精品欧美 | 美国av大片| 亚洲干视频在线观看 | 丁香婷婷综合色啪 | 黄色国产在线观看 | 在线欧美小视频 | 九七视频在线观看 | 99亚洲天堂 | 国产精品一区二区麻豆 | 欧美午夜精品久久久久久孕妇 | 欧美一级免费高清 | av电影久久 | 91精品国自产在线观看欧美 | 操天天操| 欧美一二区视频 | 欧美国产亚洲精品久久久8v | 色综合久久综合中文综合网 | 久久这里只有精品久久 | 免费观看一级成人毛片 | 97夜夜澡人人爽人人免费 | 狠狠狠色丁香婷婷综合激情 | 亚洲成av人电影 | 黄色的网站免费看 | 九草视频在线观看 | 精品理论片 | 久久区二区 | 狠狠狠色 | 精品国产一区二区三区av性色 | 久久午夜视频 | 91亚洲欧美| 天天躁天天狠天天透 | 干干日日 | 国产高清视频免费最新在线 | 国产精品免费看久久久8精臀av | 久久艹精品 | 日韩在线观看视频一区二区三区 | 国产精品免费一区二区三区在线观看 | 中文字幕中文 | 激情综合色综合久久综合 | 久久久久麻豆v国产 | 亚洲最新合集 | 婷婷av网| 欧美91精品久久久久国产性生爱 | 二区三区av | 国产成人精品一区二区三区福利 | 日日爱av| 久久精品福利视频 | 日韩欧美精品在线 | 午夜视频不卡 | 国产精品高清在线 | 免费 在线 中文 日本 | 久久综合国产伦精品免费 | 国产精品99精品久久免费 | 久久国产精品免费看 | 在线免费视频一区 | 男女拍拍免费视频 | 亚洲国产免费看 | 丝袜美女在线观看 | 91视频在线自拍 | 视频在线观看国产 | 韩国av在线播放 | 日韩一级电影在线观看 | 午夜在线免费观看 | 91视频免费观看 | 91在线观看欧美日韩 | 亚洲激情在线观看 | 欧美日韩xx | 日韩精品一区二区免费视频 | 天天爽夜夜爽人人爽一区二区 | 欧美动漫一区二区三区 | 福利在线看片 | 岛国av在线免费 | 国产亚洲精品久 | 中文字幕一区二区在线观看 | 91精彩视频在线观看 | 亚州精品天堂中文字幕 | 精品一区二区在线看 | av高清一区二区三区 | 国产又粗又长的视频 | 日韩极品视频在线观看 | 色综合天天狠天天透天天伊人 | 96av在线| 中文字幕在线观看播放 | 亚洲精品美女久久久 | 欧美一进一出抽搐大尺度视频 | 久久久久免费视频 | 精品国产一区二区久久 | 久久午夜影院 | 91在线文字幕 | 99视频99 | 国产中文字幕视频在线 | 国产精品乱码一区二三区 | 久久精品一区二区三区视频 | 91精品视频观看 | 人人干干人人 | 超级碰99 | 国产亚洲免费的视频看 | 国产视频久久久久 | 久草视频在线观 | 婷婷在线综合 | 国产精品第54页 | 国产在线观看你懂的 | 国产在线观看一区 | 黄色资源网站 | 综合婷婷丁香 | 日韩在线播放欧美字幕 | 三级黄色免费 | 亚洲精品女人久久久 | 天天射天天艹 | 久久免费99精品久久久久久 | 黄色av电影一级片 | 国精产品999国精产品岳 | 五月天色网站 | 国产精品久久久久久久久久久杏吧 | 久草新在线 | 日韩欧美大片免费观看 | 精品亚洲午夜久久久久91 | 中文字幕一区二区三区久久 | 激情五月视频 | 久久综合99 | 国产高清在线a视频大全 | 视频国产一区二区三区 | 久久综合久久综合久久 | 国产成人亚洲在线观看 | 中文字幕在线看视频 | 天天干,天天射,天天操,天天摸 | 日韩大片在线观看 | 午夜在线观看影院 | 国产男女爽爽爽免费视频 | 亚洲a在线观看 | 97超碰人人澡人人 | 欧美日韩一区二区免费在线观看 | 天天色天天 | 国产xx视频 | 黄色成人91| 天天综合久久综合 | 欧美日韩一区二区三区不卡 | 九九热久久久 | 麻豆视频在线免费观看 | 五月婷婷视频在线观看 | 成人精品999| 久久亚洲人 | 精品国精品自拍自在线 | 日韩大片在线免费观看 | 六月丁香激情网 | 久草视频在线观 | 成人午夜电影在线观看 | 久久久亚洲影院 | 五月天激情婷婷 | 草久视频在线观看 | 国产色妞影院wwwxxx | 成人a在线观看高清电影 | 91tv国产成人福利 | 香蕉视频亚洲 | 色999五月色 | 91九色视频| 黄色大片免费播放 | 亚洲综合欧美精品电影 | adn—256中文在线观看 | 久久黄色成人 | 99久久夜色精品国产亚洲96 | 中文字幕一区二区三区在线观看 | 亚洲观看黄色网 | 欧美日韩国产伦理 | 福利视频午夜 | 天天干天天拍天天操 | 日韩高清一区在线 | 日日干天天爽 | 婷婷色在线资源 | 一级理论片在线观看 | 香蕉久草 | www激情com| 色网站免费在线观看 | 国产成人在线综合 | 亚洲爱爱视频 | 玖玖视频 | 日韩三级视频 | 天天干,夜夜爽 | 中文超碰字幕 | 超碰成人免费电影 | 日韩美在线观看 | 日韩欧美国产免费播放 | 天天射天天干天天操 | 国产一区二区三区免费视频 | 亚洲精品中文在线资源 | 麻豆一精品传二传媒短视频 | 亚洲精品色婷婷 | 粉嫩aⅴ一区二区三区 | 国产精品 欧美 日韩 | 久久久国际精品 | 国产 一区二区三区 在线 | 国产精品成人av久久 | 97碰碰碰 | av网站免费线看精品 | 在线亚洲天堂网 | 国产区精品 | 久久天堂影院 | 国产成人精品久久久 | 在线观看一区视频 | 91精品啪在线观看国产线免费 | 99激情网 | 国产91免费在线 | 中国美女一级看片 | 色网影音先锋 | 91在线产啪| 精品中文字幕在线 | 亚洲第一av在线播放 | 97国产精品一区二区 | 国产一区二区三区免费视频 | av免费在线观看网站 | 亚洲国产精品视频在线观看 | 免费视频你懂得 | 色停停五月天 | 狠狠色噜噜狠狠 | 国产xx在线| 亚洲午夜久久久综合37日本 | 免费av片在线 | 国内成人av | 热精品 | 亚洲经典视频 | 天天翘av| 四虎在线观看网址 | 成人动图 | 黄色三级免费观看 | 亚洲蜜桃av | 日韩精品大片 | 九九热在线播放 | 最新成人av | 亚洲精品免费播放 | 欧美最新大片在线看 | 在线只有精品 | 最新av网址大全 | 99成人精品 | 插综合网 | 伊人婷婷激情 | 久草精品视频在线看网站免费 | 久久电影国产免费久久电影 | 人人爽人人爽人人片av免 | 欧美一区二区三区免费观看 | 九九热视频在线免费观看 | 日本精油按摩3 | 国产高清久久 | 成人网在线免费视频 | 九九在线免费视频 | aⅴ视频在线 | 国产精品成人在线 | 免费看一级特黄a大片 | 521色香蕉网站在线观看 | 国产毛片aaa| 激情av网址 | 国产一级精品在线观看 | 国产免费视频在线 | 91少妇精拍在线播放 | 国产亚洲精品久久久久动 | av一区二区三区在线观看 | 久久九九久久九九 | 99色| 国产视频97 | 九九热免费视频在线观看 | 成人免费观看视频网站 | 精品国产免费人成在线观看 | 日韩女同av | 亚州日韩中文字幕 | 黄色在线观看免费网站 | 涩涩色亚洲一区 | 五月天亚洲精品 | 国产精久久久久久久 | 天天操天天操天天干 | 超碰人人做 | 欧洲成人av | 91激情视频在线播放 | 亚洲一级二级 | 亚洲精品理论片 | 91免费网站在线观看 | 91 在线视频 | 久久久久五月 | 色偷偷人人澡久久超碰69 | 中文字幕av一区二区三区四区 | 一级一片免费观看 | 999久久久久久 | 日韩a欧美 | 国产精品网站一区二区三区 | 精品国模一区二区三区 | 国产精品一区二区三区在线播放 | 日本久久免费视频 | 亚洲一区日韩精品 | 国产色视频网站 | 久久艹综合 | av色综合| av中文在线播放 | 久久精品美女视频网站 | 亚洲激情六月 | 日韩精品视频在线观看网址 | 在线观看免费国产小视频 | 日韩资源在线播放 | 国内精品99 | 欧美性生活久久 | 97色婷婷| 亚洲一区美女视频在线观看免费 | 婷婷在线网站 | 免费看高清毛片 | 亚洲精品小区久久久久久 | 狠狠躁夜夜躁人人爽超碰91 | 天天干夜夜想 | 国产精品专区一 | 免费亚洲一区二区 | 久热超碰 | 一区二区精品视频 | 亚洲三级在线免费观看 | 精品美女久久久久久免费 | 香蕉久草 | 国产一区二区三区免费在线观看 | 久久婷婷色综合 | 亚洲一区av| 在线观看国产麻豆 | av福利电影 | 日韩av在线资源 | 国产亚洲婷婷 | 奇米先锋| 日韩免费在线 | 狠狠综合久久av | 天天干天天射天天插 | 成年人在线免费看视频 | 欧美成人在线网站 | 97精品一区 | 黄色成人影院 | 国产亚洲精品电影 | 日韩精品2区 | 国产精品自产拍在线观看网站 | 国产精品免费在线播放 | 激情综合五月天 | 激情电影影院 | 日韩国产精品久久久久久亚洲 | 黄a网站| 91免费国产在线观看 | 欧美在线久久 | 日韩在线免费观看视频 | 91精品在线免费观看视频 | 日韩欧美精品免费 | 亚洲精品动漫久久久久 | 亚洲国产成人久久综合 | 狠狠狠狠狠狠干 | 天天色天天操天天爽 | 亚洲成人av电影 | av电影在线不卡 | 成人在线视频论坛 | 五月天天色| aav在线| 精品久久久久久久久亚洲 | 免费观看的av | 天天色天天色 | 日韩视频免费 | 亚洲一区二区高潮无套美女 | 特级毛片在线观看 | 少妇bbw搡bbbb搡bbbb | 日韩av在线免费看 | 天天干,天天射,天天操,天天摸 | 日韩久久久 | 国产午夜在线观看 | 免费在线| 婷婷久久综合网 | 国产精品亚洲成人 | 日韩在线免费高清视频 | 午夜久久久久久久久久久 | 久久精品国产99国产 | 五月天婷婷在线观看视频 | 精品国产一区二 | 色在线免费| 色网av| 午夜精品久久久久99热app | 久久综合五月天 | 九九爱免费视频在线观看 | 狠狠操.com | 九九热国产视频 | 狠狠狠狠狠狠天天爱 | 久久精品99精品国产香蕉 | 日本久久中文字幕 | 99草视频在线观看 | 亚洲成人av电影在线 | 欧美视频网址 | 视频在线观看入口黄最新永久免费国产 | 免费国产一区二区视频 | av大片网址 | 色婷婷狠狠五月综合天色拍 | 久草久热 | 91精品导航 | 免费在线观看av电影 | 亚洲欧美va | 成av人电影| 欧美日韩国产在线观看 | 国产小视频国产精品 | 99视频+国产日韩欧美 | 激情五月婷婷综合网 | 91麻豆网站 | 亚洲人片在线观看 | 黄色av高清 | 亚洲精品成人 | 激情 一区二区 | www色| 国产在线高清视频 | 久久午夜电影 | 99激情网 | av黄色av| 天天爱天天操天天射 | 成人羞羞视频在线观看免费 | 国产一级h | 丁香综合激情 | 色香蕉在线视频 | 国产精品1区2区3区 久久免费视频7 | 97色婷婷成人综合在线观看 | 亚洲综合视频在线 | 免费麻豆 | 日韩最新中文字幕 | 国产成人一区二区啪在线观看 | 日韩欧美综合 | www色,com| 五月婷婷中文网 |