備註:

在 Oracle Linux 上執行控制群組版本 2

簡介

控制群組 (cgroups) 是一個 Linux 核心功能,限制、設定優先順序及配置資源 (例如 CPU 時間、記憶體和執行處理作業) 的網路頻寬。

本教學課程將引導您使用 cgroups v2,限制使用者處理作業的 CPU 時間。

目標

在本實驗室中,您將瞭解:

必要條件

設定實驗室環境

注意:使用免費實驗室環境時,請參閱 Oracle Linux Lab Basics 以取得連線和其他使用指示。

開始使用實驗室之前,我們需要完成一些內務部件物品。建立的項目可用來示範 cgroups 的限制功能。

建立載入產生命令檔

  1. 如果尚未連線,請開啟終端機,透過 ssh 連線到 ol8-server 系統。

    ssh oracle@<ip_address_of_ol8-server>
    
  2. 建立 foo.exe 命令檔。

    echo '#!/bin/bash
    
    /usr/bin/sha1sum /dev/zero' > foo.exe
    
  3. foo.exe 命令檔複製到 $PATH 中的位置並設定適當權限。

    sudo mv foo.exe /usr/local/bin/foo.exe
    sudo chown root:root /usr/local/bin/foo.exe
    sudo chmod 755 /usr/local/bin/foo.exe
    

    注意: (選擇性) 如果使用 SELinux enforcing 執行:

    sudo sestatus
    

    執行下列命令,在複製和變更權限之後修正 SELinux 標籤:

    sudo /sbin/restorecon -v /usr/local/bin/foo.exe
    

建立載入產生服務

  1. 建立 foo.service 檔案。

    echo '[Unit]
    Description=the foo service
    After=network.target
    
    [Service]
    ExecStart=/usr/local/bin/foo.exe
    
    [Install]
    WantedBy=multi-user.target' > foo.service
    
  2. foo.service 程序檔複製到 systemd 程序檔所在的位置,並設定適當的權限。

    sudo mv foo.service /etc/systemd/system/foo.service
    sudo chown root:root /etc/systemd/system/foo.service
    sudo chmod 644 /etc/systemd/system/foo.service
    

    注意: (選擇性) 如果使用 SELinux enforcing 執行,請執行下列命令,在複製及變更權限之後修正 SELinux 標籤:

    sudo /sbin/restorecon -v /etc/systemd/system/foo.service
    
  3. 重新載入常駐程式,讓系統辨識新服務。

    sudo systemctl daemon-reload
    
  4. 啟動 foo.service 並檢查其狀態。

    sudo systemctl start foo.service
    sudo systemctl status foo.service
    

建立使用者

其他使用者允許根據這些不同的帳戶和不同的 CPU 權重執行產生負載命令檔。

  1. 建立使用者並設定密碼。

    sudo useradd -u 8000 ralph
    sudo useradd -u 8001 alice
    echo "ralph:oracle" | sudo chpasswd
    echo "alice:oracle" | sudo chpasswd
    
  2. 允許 SSH 連線。

    oracle 使用者帳戶複製 SSH 金鑰。

    sudo mkdir /home/ralph/.ssh
    sudo cp /home/oracle/.ssh/authorized_keys /home/ralph/.ssh/authorized_keys
    sudo chown -R ralph:ralph /home/ralph/.ssh
    sudo chmod 700 /home/ralph/.ssh
    sudo chmod 600 /home/ralph/.ssh/authorized_keys
    
  3. alice 使用者重複上述動作。

    sudo mkdir /home/alice/.ssh
    sudo cp /home/oracle/.ssh/authorized_keys /home/alice/.ssh/authorized_keys
    sudo chown -R alice:alice /home/alice/.ssh
    sudo chmod 700 /home/alice/.ssh
    sudo chmod 600 /home/alice/.ssh/authorized_keys
    
  4. 開啟新的終端機,確認 SSH 連線可以運作。

    ssh ralph@<ip_address_of_ol8-server>
    

    然後 exit 階段作業,並對下列使用者重複。

    ssh alice@<ip_address_of_ol8-server>
    

    結束階段作業,並關閉終端機視窗。

掛載 cgroups v2

Oracle Linux 預設會在開機時掛載 v1 群組。若要使用 cgroups v2,您必須手動配置啟動核心參數。

  1. 返回您以 oracle 身分登入的終端機。

  2. 新增 cgroups v2 systemd 核心參數。

    sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
    

    您可以改為執行 sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=1",只指定目前的啟動項目。

  3. 重新啟動。

    sudo reboot
    

    重新啟動需要幾分鐘的時間完成。

    注意:在重新啟動完成且 sshd 常駐程式正在執行中之前,您將無法 ssh 進入系統。

  4. 請透過 ssh 重新連線至 ol8-server 系統。

    ssh oracle@<ip_address_of_ol8-server>
    
  5. 驗證 cgroups v2 已掛載。

    sudo mount -l | grep cgroup
    

    範例輸出:

    cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate)
    
  6. 檢查掛載之目錄 cgroups 的內容 。

    ll /sys/fs/cgroup
    

    範例輸出:

    total 0
    -r--r--r--.  1 root root 0 Mar 13 21:20 cgroup.controllers
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cgroup.max.depth
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cgroup.max.descendants
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cgroup.procs
    -r--r--r--.  1 root root 0 Mar 13 21:20 cgroup.stat
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cgroup.subtree_control
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cgroup.threads
    -rw-r--r--.  1 root root 0 Mar 13 21:20 cpu.pressure
    -r--r--r--.  1 root root 0 Mar 13 21:20 cpuset.cpus.effective
    -r--r--r--.  1 root root 0 Mar 13 21:20 cpuset.mems.effective
    drwxr-xr-x.  2 root root 0 Mar 13 21:20 init.scope
    -rw-r--r--.  1 root root 0 Mar 13 21:20 io.pressure
    -rw-r--r--.  1 root root 0 Mar 13 21:20 memory.pressure
    drwxr-xr-x. 87 root root 0 Mar 13 21:20 system.slice
    drwxr-xr-x.  4 root root 0 Mar 13 21:24 user.slice
    

    輸出會在其預設位置顯示 root 控制群組。該目錄包含介面檔案,前面加上 cgroup,而與 systemd 相關的目錄 (結尾為 .scope.slice)。

使用虛擬檔案系統

在啟動之前,我們需要一些有關掛載於 /sys/fs/cgroup 的 cgroups 虛擬檔案系統。

  1. 顯示參與每個人之 CPU 的 CPU。

    cat /sys/fs/cgroup/cpuset.cpus.effective
    

    範例輸出:

    [oracle@ol8-server ~]$ cat /sys/fs/cgroup/cpuset.cpus.effective
    0-1
    

    我們的測試方塊是部署在 VM.Standard2.1 資源配置上的 Oracle Linux 8 執行處理,此為雙核心系統。

  2. 顯示作用中的控制器。

    cat /sys/fs/cgroup/cgroup.controllers
    

    範例輸出:

    [oracle@ol8-server ~]$ cat /sys/fs/cgroup/cgroup.controllers
    cpuset cpu io memory pids rdma
    

    稍後會在此實驗室使用 CPU 時,最好查看 CPU 控制器。

  3. 顯示由 oracle 產生的處理作業。

    首先,我們必須決定 oracle 的使用者 ID (UID)。

    who
    id
    

    範例輸出:

    [oracle@ol8-server ~]$ who
    oracle   pts/0        2022-03-13 21:23 (10.39.209.157)
    [oracle@ol8-server ~]$ id
    uid=1001(oracle) gid=1001(oracle) groups=1001(oracle),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    

    使用 UID 時,我們可以找到 oracle 使用者片段。

    cd /sys/fs/cgroup/user.slice
    ls
    

    範例輸出:

    [oracle@ol8-server ~]$ cd /sys/fs/cgroup/user.slice
    [oracle@ol8-server user.slice]$ ls
    cgroup.controllers      cgroup.subtree_control  memory.events        memory.pressure      pids.max
    cgroup.events           cgroup.threads          memory.events.local  memory.stat          user-0.slice
    cgroup.freeze           cgroup.type             memory.high          memory.swap.current  user-1001.slice
    cgroup.max.depth        cpu.pressure            memory.low           memory.swap.events   user-989.slice
    cgroup.max.descendants  cpu.stat                memory.max           memory.swap.max
    cgroup.procs            io.pressure             memory.min           pids.current
    cgroup.stat             memory.current          memory.oom.group     pids.events
    

    Systemd 指派每個使用者一個名為 user-<UID>.slice 的片段。那個目錄底下是什麼?

    cd user-1001.slice
    ls
    

    範例輸出:

    [oracle@ol8-server user.slice]$ cd user-1001.slice/
    [oracle@ol8-server user-1001.slice]$ ls
    cgroup.controllers  cgroup.max.descendants  cgroup.threads  io.pressure        user-runtime-dir@1001.service
    cgroup.events       cgroup.procs            cgroup.type     memory.pressure
    cgroup.freeze       cgroup.stat             cpu.pressure    session-3.scope
    cgroup.max.depth    cgroup.subtree_control  cpu.stat        user@1001.service
    

    這些是 oracle 使用者的最上層 cgroups。不過,cgroup.procs 中沒有列出任何程序。所以,使用者處理作業的清單為何?

    cat cgroup.procs
    

    範例輸出:

    [oracle@ol8-server user-1001.slice]$ cat cgroup.procs
    [oracle@ol8-server user-1001.slice]$
    

    oracle 在此實驗室開頭開啟 SSH 階段作業時,使用者階段作業便會建立範圍子單位。在此範圍下,我們可以檢查 cgroup.procs 以取得該階段作業下產生的處理作業清單。

    注意:使用者可能會有多個以系統連線數目為基礎的階段作業;因此,請視需要取代下方範例中的 3。

    cd session-3.scope
    ls
    cat cgroup.procs
    

    範例輸出:

    [oracle@ol8-server user-1001.slice]$ cd session-3.scope/
    [oracle@ol8-server session-3.scope]$ ls
    cgroup.controllers  cgroup.max.depth        cgroup.stat             cgroup.type   io.pressure
    cgroup.events       cgroup.max.descendants  cgroup.subtree_control  cpu.pressure  memory.pressure
    cgroup.freeze       cgroup.procs            cgroup.threads          cpu.stat
    [oracle@ol8-server session-3.scope]$ cat cgroup.procs
    3189
    3200
    3201
    54217
    

    現在我們很難找到程序,可以使用 systemd-cgls 在類似樹狀結構的檢視中顯示相同的資訊。

    注意:從虛擬檔案系統內執行時,systemd-cgls 會將 cgroup 輸出限制在目前的工作目錄。

    cd /sys/fs/cgroup/user.slice/user-1001.slice
    systemd-cgls
    

    範例輸出:

    [oracle@ol8-server user-1001.slice]$ systemd-cgls
    Working directory /sys/fs/cgroup/user.slice/user-1001.slice:
    ├─session-3.scope
    │ ├─ 3189 sshd: oracle [priv]
    │ ├─ 3200 sshd: oracle@pts/0
    │ ├─ 3201 -bash
    │ ├─55486 systemd-cgls
    │ └─55487 less
    └─user@1001.service
      └─init.scope
        ├─3193 /usr/lib/systemd/systemd --user
        └─3195 (sd-pam)
    

限制使用的 CPU 核心

使用 cgroups v2 時,systemd 對 cpuset 控制器有完整的控制。此層次的控制可讓管理員只對特定的 CPU 核心排定工作。

  1. 檢查 CPU 的 user.slice

    cd /sys/fs/cgroup/user.slice
    ls
    cat ../cpuset.cpus.effective
    

    範例輸出:

    [oracle@ol8-server cgroup]$ cd /sys/fs/cgroup/user.slice/
    [oracle@ol8-server user.slice]$ ls
    cgroup.controllers      cgroup.subtree_control  memory.events        memory.pressure      pids.max
    cgroup.events           cgroup.threads          memory.events.local  memory.stat          user-0.slice
    cgroup.freeze           cgroup.type             memory.high          memory.swap.current  user-1001.slice
    cgroup.max.depth        cpu.pressure            memory.low           memory.swap.events   user-989.slice
    cgroup.max.descendants  cpu.stat                memory.max           memory.swap.max
    cgroup.procs            io.pressure             memory.min           pids.current
    cgroup.stat             memory.current          memory.oom.group     pids.events
    [oracle@ol8-server user.slice]$ cat ../cpuset.cpus.effective
    0-1
    

    cpuset.cpus.effective 顯示 user.slice 所使用的實際核心。如果參數不存在於特定的 cgroup 目錄,或並未設定它,則值會繼承自父項,而此種情況將成為最上層 cgroup 根目錄。

  2. system 和使用者 0、1001 和 989 磁碟片段限制為 CPU 核心 0。

    cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective
    sudo systemctl set-property system.slice AllowedCPUs=0
    cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective
    

    範例輸出:

    [oracle@ol8-server user.slice]$ cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective
    cat: /sys/fs/cgroup/system.slice/cpuset.cpus.effective: No such file or directory
    [oracle@ol8-server user.slice]$ sudo systemctl set-property system.slice AllowedCPUs=0
    [oracle@ol8-server user.slice]$ cat /sys/fs/cgroup/system.slice/cpuset.cpus.effective
    0
    

    注意:No such file or directory 表示 system 片段預設會繼承其來自父項的 cpuset.cpus.effective 值。

    sudo systemctl set-property user-0.slice AllowedCPUs=0
    sudo systemctl set-property user-1001.slice AllowedCPUs=0
    sudo systemctl set-property user-989.slice AllowedCPUs=0
    
  3. ralph 使用者限制在 CPU 核心 1。

    sudo systemctl set-property user-8000.slice AllowedCPUs=1
    cat /sys/fs/cgroup/user.slice/user-8000.slice/cpuset.cpus.effective
    

    範例輸出:

    [oracle@ol8-server ~]$ sudo systemctl set-property user-8000.slice AllowedCPUs=1
    [oracle@ol8-server ~]$ cat /sys/fs/cgroup/user.slice/user-8000.slice/cpuset.cpus.effective
    1
    
  4. 開啟新的終端機,並且透過 ssh 以 ralph 身分連線到 ol8-server 系統。

    ssh ralph@<ip_address_of_ol8-server>
    
  5. 使用 foo.exe 命令檔測試。

    foo.exe &
    

    檢查結果。

    top
    

    top 執行之後,按一下 1 key 即可個別顯示 CPU。

    範例輸出:

    top - 18:23:55 up 21:03,  2 users,  load average: 1.03, 1.07, 1.02
    Tasks: 155 total,   2 running, 153 sleeping,   0 stopped,   0 zombie
    %Cpu0  :  6.6 us,  7.0 sy,  0.0 ni, 84.8 id,  0.0 wa,  0.3 hi,  0.3 si,  1.0 st
    %Cpu1  : 93.0 us,  6.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.7 hi,  0.3 si,  0.0 st
    MiB Mem :  14707.8 total,  13649.1 free,    412.1 used,    646.6 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  13993.0 avail Mem
    
       PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
    226888 ralph     20   0  228492   1808   1520 R  99.7   0.0 199:34.27 sha1sum
    269233 root      20   0  223724   6388   1952 S   1.3   0.0   0:00.04 pidstat
       1407 root      20   0  439016  41116  39196 S   0.3   0.3   0:17.81 sssd_nss
       1935 root      20   0  236032   3656   3156 S   0.3   0.0   0:34.34 OSWatcher
       2544 root      20   0  401900  40292   9736 S   0.3   0.3   0:10.62 ruby
          1 root      20   0  388548  14716   9508 S   0.0   0.1   0:21.21 systemd
    ...
    

    鍵入 q 以結束頂端。

  6. 檢查執行處理之處理器的替代方式。

    ps -eo pid,psr,user,cmd | grep ralph
    

    範例輸出:

    [ralph@ol8-server ~]$ ps -eo pid,psr,user,cmd | grep ralph
     226715   1 root     sshd: ralph [priv]
     226719   1 ralph    /usr/lib/systemd/systemd --user
     226722   1 ralph    (sd-pam)
     226727   1 ralph    sshd: ralph@pts/2
     226728   1 ralph    -bash
     226887   1 ralph    /bin/bash /usr/local/bin/foo.exe
     226888   1 ralph    /usr/bin/sha1sum /dev/zero
     269732   1 ralph    ps -eo pid,psr,user,cmd
     269733   1 ralph    grep --color=auto ralph
    

    psr 資料欄是 cmd 的 CPU 數目或實際處理作業的 CPU 數目。

  7. 結束並關閉用來以 ralph 身分登入的終端機視窗。

  8. 終止 foo.exe 工作。

    切換回您以 oracle 身分登入的終端機,然後執行下列指令。

    sudo pkill sha1sum
    

調整使用者的 CPU 重量

享受 alice 連結的時間。她有一個要完成的重要工作,因此我們會給她那對 CPU 的正常優先權兩次。

  1. alice 指定至與 ralph 相同的 CPU。

    sudo systemctl set-property user-8001.slice AllowedCPUs=1
    cat /sys/fs/cgroup/user.slice/user-8001.slice/cpuset.cpus.effective
    
  2. 設定 CPUWeight

    sudo systemctl set-property user-8001.slice CPUWeight=200
    cat /sys/fs/cgroup/user.slice/user-8001.slice/cpu.weight
    

    預設加權為 100,因此 200 為該數字的兩倍。

  3. 開啟新的終端機,並且透過 ssh 以 ralph 身分連線到 ol8-server 系統。

    ssh ralph@<ip_address_of_ol8-server>
    
  4. ralph 身分執行 foo.exe

    foo.exe &
    
  5. Open another new terminal and connect via ssh as alice to the ol8-server system.

    ssh alice@<ip_address_of_ol8-server>
    
  6. alice 身分執行 foo.exe

    foo.exe &
    
  7. 請透過 top 驗證 alice 是否取得更高的優先順序。

    top
    

    頂部執行後,按一下 1 key 以個別顯示 CPU。

    範例輸出:

    top - 20:10:55 up 25 min,  3 users,  load average: 1.29, 0.46, 0.20
    Tasks: 164 total,   3 running, 161 sleeping,   0 stopped,   0 zombie
    %Cpu0  :  0.0 us,  0.0 sy,  0.0 ni, 96.5 id,  0.0 wa,  0.0 hi,  3.2 si,  0.3 st
    %Cpu1  : 92.4 us,  7.6 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    MiB Mem :  15715.8 total,  14744.6 free,    438.5 used,    532.7 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  15001.1 avail Mem 
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND  
       7934 alice     20   0   15800   1768   1476 R  67.0   0.0   0:36.15 sha1sum  
       7814 ralph     20   0   15800   1880   1592 R  33.3   0.0   0:34.60 sha1sum  
          1 root      20   0  388476  14440   9296 S   0.0   0.1   0:02.22 systemd  
          2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd
    ...
    
  8. 返回以 oracle 使用者身分登入的終端機。

  9. 使用 foo.service 載入 system.slice

    sudo systemctl start foo.service
    

    現在看看最高的輸出仍在執行 alice 終端機視窗中。請參閱 foo.service 使用 CPU 0,而使用者則根據 CPU 的加權分割 CPU 1。

    範例輸出:

    top - 19:18:15 up 21:57,  3 users,  load average: 2.15, 2.32, 2.25
    Tasks: 159 total,   4 running, 155 sleeping,   0 stopped,   0 zombie
    %Cpu0  : 89.1 us,  7.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.7 hi,  0.3 si,  2.6 st
    %Cpu1  : 93.7 us,  5.3 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.7 hi,  0.3 si,  0.0 st
    MiB Mem :  14707.8 total,  13640.1 free,    420.5 used,    647.2 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  13984.3 avail Mem
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     280921 root      20   0  228492   1776   1488 R  93.4   0.0   0:07.74 sha1sum
     279185 alice     20   0  228492   1816   1524 R  65.6   0.0   7:35.18 sha1sum
     279291 ralph     20   0  228492   1840   1552 R  32.8   0.0   7:00.30 sha1sum
       2026 oracle-+  20   0  935920  29280  15008 S   0.3   0.2   1:03.31 gomon
          1 root      20   0  388548  14716   9508 S   0.0   0.1   0:22.30 systemd
          2 root      20   0       0      0      0 S   0.0   0.0   0:00.10 kthreadd
    ...
    

指定 CPU 配額

最後,我們將把 CPU 時間限制在 ralph

  1. 返回以 oracle 使用者身分登入的終端機。

  2. 將配額設為 5%

    sudo systemctl set-property user-8000.slice CPUQuota=5%
    

    這項變更會立即生效,如在 alice 使用者終端機中運作的頂部輸出中所示。

    範例輸出:

    top - 19:24:53 up 22:04,  3 users,  load average: 2.21, 2.61, 2.45
    Tasks: 162 total,   4 running, 158 sleeping,   0 stopped,   0 zombie
    %Cpu0  : 93.0 us,  4.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.7 hi,  0.0 si,  1.7 st
    %Cpu1  : 91.7 us,  5.6 sy,  0.0 ni,  0.0 id,  0.0 wa,  1.0 hi,  1.0 si,  0.7 st
    MiB Mem :  14707.8 total,  13639.4 free,    420.0 used,    648.4 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.  13984.7 avail Mem
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     280921 root      20   0  228492   1776   1488 R  97.4   0.0   6:26.75 sha1sum
     279185 alice     20   0  228492   1816   1524 R  92.1   0.0  12:21.12 sha1sum
     279291 ralph     20   0  228492   1840   1552 R   5.3   0.0   8:44.84 sha1sum
          1 root      20   0  388548  14716   9508 S   0.0   0.1   0:22.48 systemd
          2 root      20   0       0      0      0 S   0.0   0.0   0:00.10 kthreadd
    ...
    
  3. 使用 oracle 終端機視窗回復 ralph 使用者上的大寫字。

echo "max 100000" | sudo tee -a user-8000.slice/cpu.max

配額會寫入 cpu.max 檔案,且預設值為 max 100000

範例輸出:

[oracle@ol8-server user.slice]$ echo "max 100000" | sudo tee -a user-8000.slice/cpu.max
max 100000

您可以啟用 cgroups v2,將使用者在系統負載時限制為特定 CPU,然後將其鎖定成僅使用該 CPU 的百分比。檢視其他資源,以便瞭解 Oracle Linux。

其他相關資訊

請參閱其他相關資源:

其他學習資源

探索 docs.oracle.com/learn 上的其他實驗室,或是存取更多免費學習內容至 Oracle Learning YouTube 通道。此外,瀏覽 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。

如需產品文件,請瀏覽 Oracle Help Center