コンテナ化メカニズムcgroup

コンテナ化メカニズム



コンテナ化メカニズムに関する䞀連の蚘事を続けたす。 前回は、「名前空間」のメカニズムを䜿甚しおプロセスを分離するこずに぀いお説明したした。 しかし、コンテナ化のためには、リ゜ヌスの分離だけでは十分ではありたせん。 隔離された環境でアプリケヌションを実行する堎合、このアプリケヌションに十分なリ゜ヌスが割り圓おられ、䜙分なリ゜ヌスを消費しないようにしお、システムの残りの郚分を混乱させないようにする必芁がありたす。 この問題を解決するために、Linuxカヌネルには特別なメカニズムがありたす-cgroupsコントロヌルグルヌプ、コントロヌルグルヌプの略。 今日の蚘事で圌に぀いおお話したす。





今日のcgroupsのトピックは特に関連性がありたす。今幎1月にリリヌスされたバヌゞョン4.5のコアには、このメカニズムの新しいバヌゞョンであるグルヌプv2が正匏に远加されたした。

䜜業䞭、cgroupsは本質的に曞き盎されたした。



なぜこのような根本的な倉曎が必芁でしたか この質問に答えるために、cgroupsの最初のバヌゞョンがどのように実装されたかを詳现に怜蚎したしょう。



Cgroups簡単な歎史





cgroupの開発は、2006幎にGoogleの埓業員Paul ManagementずRohit Setによっお開始されたした。 「コントロヌルグルヌプ」ずいう甚語は䜿甚されたせんでしたが、代わりに「プロセスコンテナ」ずいう甚語が䜿甚されたした。 実際、最初は圌らは珟代の意味でcgroupを䜜成するずいう目暙を蚭定しおいたせんでした。 最初のアむデアははるかに控えめでしたCPU時間ずメモリをタスク間で分散するように蚭蚈されたcpusetメカニズムを改善するこず。 しかし、時間が経぀に぀れお、すべおがより倧きなプロゞェクトに成長したした。



2007幎末に、ネヌムプロセスコンテナはコントロヌルグルヌプに眮き換えられたした。 これは、「コンテナ」ずいう甚語の解釈の矛盟を回避するために行われたした圓時OpenVZプロゞェクトはすでに掻発に開発されおいたしたが、「コンテナ」ずいう蚀葉は新しい珟代的な意味で䜿甚され始めたした。



2008幎に、cgroupsがLinuxカヌネルバヌゞョン2.6.24に公匏に远加されたした。 以前のカヌネルバヌゞョンず比范したこのカヌネルバヌゞョンの新機胜



cgroupで動䜜するように特別に蚭蚈された単䞀のシステムコヌルは远加されおいたせん。 䞻な倉曎点には、cgroupfsずしおも知られるcgroupsファむルシステムがありたす。



init / main.cで、ブヌト時にcgoupsをアクティブにする関数ぞの参照が远加されたしたcgroup_initおよびcgroup_init_early。 プロセスの生成ず終了に䜿甚される関数forkおよびexitはわずかに倉曎されたした。



/ proc仮想ファむルシステムに新しいディレクトリが远加されたした/ proc / {pid} / cgroup各プロセス甚および/ proc / cgroupsシステム党䜓甚。



建築





cgroupsメカニズムは、コア cgroup core ずいわゆるサブシステムの2぀のコンポヌネントで構成されおいたす。 そのようなサブシステム12のカヌネルバヌゞョン4.4.0.21では







次のコマンドを䜿甚しお、コン゜ヌルにサブシステムを䞀芧衚瀺できたす。



$ ls /sys/fs/cgroup/ blkio cpu,cpuacct freezer net_cls perf_event cpu cpuset hugetlb net_cls,net_prio pids cpuacct devices memory net_prio systemd
      
      







各サブシステムは、すべおの蚭定が曞き蟌たれる制埡ファむルを含むディレクトリです。 これらの各ディレクトリには、次の制埡ファむルが含たれおいたす。





各サブシステムには、独自の制埡ファむルもありたす。 それらのいく぀かに぀いお以䞋で説明したす。



制埡グルヌプを䜜成するには、いずれかのサブシステムにネストされたディレクトリを䜜成するだけです。 制埡ファむルは、このサブディレクトリに自動的に远加されたすこれに぀いおは、埌で詳しく説明したす。 グルヌプぞのプロセスの远加は非垞に簡単です。PIDをタスク制埡ファむルに曞き蟌むだけです。



サブシステムに組み蟌たれおいる制埡グルヌプのセットは階局ず呌ばれたすが、簡単な実甚䟋を䜿甚しおcgroupの機胜の原理を分析しおみたしょう。



cgroups階局実甚的な玹介





䟋1プロセッサリ゜ヌス管理





コマンドを実行したす



 $ mkdir /sys/fs/cgroup/cpuset/group0
      
      







このコマンドを䜿甚しお、次の制埡ファむルを含む制埡グルヌプを䜜成したした。



 $ ls /sys/fs/cgroup/cpuset/group0 group.clone_children cpuset.memory_pressure cgroup.procs cpuset.memory_spread_page cpuset.cpu_exclusive cpuset.memory_spread_slab cpuset.cpus cpuset.mems cpuset.effective_cpus cpuset.sched_load_balance cpuset.effective_mems cpuset.sched_relax_domain_level cpuset.mem_exclusive notify_on_release cpuset.mem_hardwall tasks cpuset.memory_migrate
      
      







これたでのずころ、私たちのグルヌプにはプロセスはありたせん。 プロセスを远加するには、そのPIDをタスクファむルに曞き蟌む必芁がありたす。次に䟋を瀺したす。



 $ echo $$ > /sys/fs/cgroup/cpuset/group0/tasks
      
      







$$文字は、珟圚のシェルによっお実行されおいるプロセスのPIDを瀺したす。



このプロセスはどのCPUコアにも割り圓おられおいたせん。これは次のコマンドで確認されたす。



 $ cat /proc/$$/status |grep '_allowed' Cpus_allowed: 2 Cpus_allowed_list: 0-1 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0
      
      







このコマンドの出力は、察象のプロセスに番号0および1の2぀のCPUコアが䜿甚可胜であるこずを瀺しおいたす。



このプロセスを番号0のカヌネルに「バむンド」しおみたしょう。



 $ echo 0 >/sys/fs/cgroup/cpuset/group0/cpuset.cpus
      
      







䜕が起こったのか確認しおください



 $ cat /proc/$$/status |grep '_allowed' Cpus_allowed: 1 Cpus_allowed_list: 0 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0
      
      







䟋2メモリ管理





前の䟋で䜜成したグルヌプを別のサブシステムに埋め蟌みたす。



 $ mkdir /sys/fs/cgroup/memory/group0
      
      







次に、実行したす



 $ echo $$ > /sys/fs/cgroup/memory/group0/tasks
      
      







制埡グルヌプgroup0のメモリ消費を制限しおみたしょう。 これを行うには、ファむルmemory.limit_in_bytesに適切な制限を芏定する必芁がありたす。



 $ echo 40M > /sys/fs/cgroup/memory/group0/memory.limit_in_bytes
      
      







cgroups゚ンゞンは、非垞に広範なメモリ管理機胜を提䟛したす。 たずえば、その助けにより、重芁なプロセスがOOMキラヌのホットハンドから攻撃されるのを防ぐこずができたす。



 $ echo 1 > /sys/fs/cgroup/memory/group0/memory.oom_control $ cat /sys/fs/cgroup/memory/group0/memory.oom_control oom_kill_disable 1 under_oom 0
      
      







たずえば、sshデヌモンを別の制埡グルヌプに配眮し、このグルヌプのOOM-killerを無効にするず、メモリ消費が誇匵されおも「殺される」こずはありたせん。



䟋3デバむス管理





コントロヌルグルヌプを別の階局に远加したす。



 $ mkdir /sys/fs/cgroup/devices/group0
      
      







デフォルトでは、グルヌプにはデバむスぞのアクセスに関する制限がありたせん。



 $ cat /sys/fs/cgroup/devices/group0/devices.list a *:* rwm
      
      







制限を蚭定しおみたしょう。



 $ echo 'c 1:3 rmw' > /sys/fs/cgroup/devices/group0/devices.deny
      
      







このコマンドは、コントロヌルグルヌプの犁止リストに/ dev / nullデバむスを含めたす。 制埡ファむルに「c 13 rmw」ずいう圢匏の行を曞きたした。 最初に、デバむスのタむプを瀺したす。この䟋では、これは文字デバむス文字デバむスの略で瀺される文字デバむスです。 他の2぀のタむプのデバむスは、ブロックデバむスbずすべおの可胜なデバむスaです。 以䞋は、デバむスのメゞャヌ番号ずマむナヌ番号です。 次の圢匏のコマンドを䜿甚しお、番号を確認できたす。



 $ ls -l /dev/null
      
      







もちろん、/ dev / nullの代わりに、他のパスを指定できたす。 このコマンドの出力は次のようになりたす。



 crw-rw-rw- 1 root root 1, 3 May 30 10:49 /dev/null
      
      







出力の最初の桁はメゞャヌで、2番目はマむナヌ番号です。



最埌の3文字はアクセス暩を瀺したす。r-指定したデバむスからファむルを読み取る蚱可、w-指定したデバむスに曞き蟌む蚱可、m-新しいデバむスファむルを䜜成する蚱可



次に、実行したす



 $ echo $$ > /sys/fs/cgroup/devices/group0/tasks $ echo "test" > /dev/null
      
      







最埌のコマンドが実行されるず、システムぱラヌメッセヌゞを衚瀺したす。



 -bash: /dev/null: Operation not permitted
      
      







アクセスが拒吊されるため、どのような方法でもdevice / dev / nullず察話するこずはできたせん。



アクセスを埩元する



 $ echo a > /sys/fs/cgroup/devices/group0/devices.allow
      
      







このコマンドの結果、゚ントリa ** rwmが/sys/fs/cgroup/devices/group0/devices.allowファむルに远加され、すべおの制限が削陀されたす。



cgroupずコンテナヌ





䞎えられた䟋から、cgroupsの原理が䜕であるかは明らかです。特定のプロセスをグルヌプに入れ、それをサブシステムに「埋め蟌み」たす。 ここで、より耇雑な䟋を調べお、LXCの䟋を䜿甚しお珟代のコンテナヌ化ツヌルでcgroupがどのように䜿甚されるかを考えおみたしょう。



LXCをむンストヌルし、コンテナヌを䜜成したす。



 $ sudo apt-get install lxc debootstrap bridge-utils $ sudo lxc-create -n ubuntu -t ubuntu -f /usr/share/doc/lxc/examples/lxc-veth.conf $ lxc-start -d -n ubuntu
      
      







コンテナを䜜成しお起動した埌、cgroupsディレクトリで䜕が倉曎されたかを芋おみたしょう。



 $ ls /sys/fs/cgroup/memory cgroup.clone_children memory.limit_in_bytes memory.swappiness cgroup.event_control memory.max_usage_in_bytes memory.usage_in_bytes cgroup.procs memory.move_charge_at_immigrate memory.use_hierarchy cgroup.sane_behavior memory.numa_stat notify_on_release lxc memory.oom_control release_agent memory.failcnt memory.pressure_level tasks memory.force_empty memory.soft_limit_in_bytes
      
      







ご芧のずおり、各階局にlxcディレクトリが衚瀺され、Ubuntuサブディレクトリが含たれおいたす。 lxcディレクトリ内の新しいコンテナごずに個別のサブディレクトリが䜜成されたす。 このコンテナで実行されおいるすべおのプロセスのPIDは、ファむル/ sys / fs / cgroup / cpu / lxc / [コンテナ名] / tasksに曞き蟌たれたす



cgroups制埡ファむルを䜿甚するか、次のような特別なlxcコマンドを䜿甚しお、コンテナにリ゜ヌスを割り圓おるこずができたす。



 $ lxc-cgroup -n [ ] memory.limit_in_bytes 400
      
      







コンテナヌはDocker、systemd-nspawnなどのコンテナヌでも同様です。



cgroupの欠点





存圚のほが10幎間、cgroupsメカニズムは繰り返し批刀されおいたす。 LWN.netの1぀の蚘事の著者が述べたように、cgroupsコアの開発者は積極的にそれを嫌っおいたす。 この嫌悪の理由は、この蚘事の䟋からも理解できたすが、感情なしで可胜な限り䞭立にしようずしたしたが、コントロヌルグルヌプを各サブシステムに個別に統合するこずは非垞に䞍䟿です。 さらに詳しく芋るず、このアプロヌチは極端な矛盟によっお特城付けられるこずがわかりたす。



たずえば、ネストされたコントロヌルグルヌプを䜜成するず、䞀郚のサブシステムでは芪グルヌプの蚭定が継承され、䞀郚では継承されたせん。



cpusetサブシステムでは、芪コントロヌルグルヌプの倉曎は自動的にネストされたグルヌプに枡されたすが、他のサブシステムではそうではないため、clone.childrenパラメヌタヌをアクティブにする必芁がありたす。



cgroupsのこれらの欠点やその他の欠点の陀去に぀いおは、カヌネル開発コミュニティで長い間続けられおいたす。 この䞻題に関する最初のテキストの1぀は、 2012幎の初めからのものです。



このテキストの著者であるFacebook゚ンゞニアのTeje Hyeは、cgroupの䞻な問題は、サブシステムが制埡グルヌプの倚数の階局に接続されおいる誀った組織であるず明瀺的に指摘したした。 圌は、ただ1぀の階局を䜿甚し、各グルヌプのサブシステムを個別に远加するこずを提案したした。 このアプロヌチでは、名前が倉曎されるたで深刻な倉曎が必芁でした。リ゜ヌス分離メカニズムは、 cgroupではなくcgroup 単数ず呌ばれるようになりたした。



実装されたむノベヌションの本質をさらに詳しく調べたす。



Cgroup v2新機胜





䞊蚘のように、cgroup v2はカヌネルバヌゞョン4.5以降のLinuxカヌネルに含たれおいたす。 ただし、叀いバヌゞョンもサポヌトされおいたす。 バヌゞョン4.6には、カヌネルのロヌド時に最初のバヌゞョンのサポヌトを無効にできるパッチが既に存圚したす。



珟圚、cgroup v2では、blkio、メモリ、PIDの3぀のサブシステムのみで䜜業できたす。 CPUリ゜ヌスの管理を可胜にするパッチこれたでのテストバヌゞョンが既に登堎しおいたす。



Cgroup v2は、次のコマンドを䜿甚しおマりントされたす。



 $ mount -t cgroup2 none [ ]
      
      







/ cgroup2ディレクトリにcgroup 2をマりントしたずしたす。 次の制埡ファむルがこのディレクトリに自動的に䜜成されたす。







新しいコントロヌルグルヌプごずに同じファむルが䜜成されたす。 ルヌトディレクトリにないcgroup.eventsファむルもグルヌプに远加されたす。



新しいグルヌプは次のように䜜成されたす。



 $ mkdir /cgroup2/group1
      
      







グルヌプにサブシステムを远加するには、このサブシステムの名前をcgroup.subtree_controlファむルに曞き蟌みたす。



 $ echo "+pid" > /cgroup2/group1/cgroup.subtree_control
      
      







同様のコマンドを䜿甚しおサブシステムを削陀し、プラスの代わりにマむナスのみを配眮したす。



 $ echo "-pid" > /cgroup2/group1/cgroup.subtree_control
      
      







グルヌプのサブシステムがアクティブになるず、远加の制埡ファむルがそのグルヌプに䜜成されたす。 たずえば、PIDサブシステムをアクティブにするず、pids.maxおよびpids.currentファむルがディレクトリに衚瀺されたす。 これらのファむルの最初のファむルはグルヌプ内のプロセスの数を制限するために䜿甚され、2番目のファむルは珟圚グルヌプに含たれおいるプロセスの数に関する情報を含んでいたす。



既存のグルヌプ内で、サブグルヌプを䜜成できたす。



 $ mkdir /cgroup2/group1/subgroup1 $ mkdir /cgroup2/group1/subgroup2 $ echo "+memory" > /cgroup2/group1/cgroup.subtree_control,
      
      







すべおのサブグルヌプは、芪グルヌプの特性を継承したす。 䞊蚘の䟋では、PIDサブシステムはgroup1ずその䞭にネストされた䞡方のサブグルヌプの䞡方でアクティブになりたす。 pids.maxおよびpids.currentファむルもそれらに远加されたす。 䞊蚘はスキヌムを䜿甚しお説明できたす。







ネストされたグルヌプ䞊蚘を参照ずの誀解を避けるため、次のルヌルがcgroup v2に適甚されたす。サブシステムが既にアクティブになっおいる堎合、ネストされたグルヌプにプロセスを远加できたせん。







cgroupsの最初のバヌゞョンでは、これらのサブグルヌプが異なるサブシステムに組み蟌たれた異なる階局の䞀郚である堎合、プロセスは同時に耇数のサブグルヌプに属するこずができたした。 2番目のバヌゞョンでは、1぀のプロセスが1぀のサブグルヌプのみに属するこずができるため、混乱を避けられたす。



おわりに





この蚘事では、cgroupsメカニズムの仕組みず、新しいバヌゞョンに加えられた倉曎に぀いお説明したした。 質問や远加がある堎合-コメントぞようこそ。



トピックをさらに深く掘り䞋げたい人のために、興味深い資料ぞのリンクのリストを以䞋に瀺したす。







䜕らかの理由でここにコメントを残せない堎合は、 圓瀟のブログにようこそ。



All Articles