Cgroup Werte von LXC Linux Containern

Aus Thomas-Krenn-Wiki
Wechseln zu: Navigation, Suche

Linux Container sind eine schlanke und effiziente Methode Linux-Systeme zu virtualisieren. Ein Linux Container ist eine Gruppe von Prozessen, die zusammen in einer isolierten Umgebung laufen. Innerhalb des Containers ergibt sich ein Bild wie in einer virtuellen Maschine, am Host-System scheint der Container als normaler Prozesse auf. Um Ressourcen zu verwalten und zu limitieren verwenden Linux Container Control Groups (cgroups). Der folgende Artikel stellt die Metriken vor, die sich per cgroups im Zusammenhang mit Linux Container verwalten lassen. Es wird dabei auch auf die Userspace Werkzeuge, unter dem Namen LXC, eingegangen.

cgroups

Control Groups sind ein Mechanismus zur Strukturierung/Verwaltung von Tasks in hierarchische(n) Gruppen. Im Speziellen können über unterschiedliche Subsysteme, Limitierungs (Accounting) Maßnahmen getroffen werden.[1]

  • cgroup: Eine Gruppe von Tasks mit Parametern eines bestimmten Subsystems.
  • Subsystem: Ein Modul, dass auf die gruppierten Tasks Ressourcen-Controlling anwendet.

Folgende Subsysteme sind aktuell verfügbar:[2]

Subsystem Zweck
cpusets Limits für CPUs und Memory Nodes für Tasks einer Gruppe.
blkio Limits für Input/Output Zugriffe auf Block Devices.
cpuacct Limits für CPU Ressourcen von Tasks einer Gruppe.
devices Erlaubt oder verbietet Zugriffe auf Devices für Gruppen.
freezer Suspend oder Resume von Tasks.
hugetlb Limits für Virtual Memory Tables.
memory Limits für Memory für Tasks in einer Gruppe.
net_cls Tagged Netzwerk-Pakete mit Class IDs, ein Traffic Controller kann IDs Prioritäten zuordnen.
net_prio Prioritäten für Netzwerk-Traffic von Tasks einer Gruppe.
cpu CPU Scheduling Verwaltung, zusammen mit cpuacct.
perf_event Monitoring Threads einer Task Gruppe auf einer CPU.

cgroups testen

Die folgenden Beispiele zeigen zwei einfache Tests mit cgroups. Erstens über den traditionellen Weg über Verzeichnisse und Dateien, zweitens über die cgmanager-utils, die unter Ubuntu mit dem Central cgroup manager daemon kommunizieren. Ubuntu setzt seit 14.04 Codename Trusty per Default einen Socket-Daemon ein, um cgroups zu verwalten. Das war in Zusammenhang mit LXC vor allem für nested Containers nötig.[3][4]

freezer Test

Die cgroup freezer übernimmt das Starten und Stoppen von Tasks.[5] Diese CGroup wird z.B. auch bei Checkpoint/Restore eingesetzt.

Im folgenden Beispiel wird ein ping Befehl mit FROZEN eingefroren, das tailf gibt keine weiteren Zeilen aus, solange der Tasks im FROZEN Status ist.

# mkdir /mnt/cgroup1
# mount -t cgroup -o freezer cgroup /mnt/cgroup1
# mkdir /mnt/cgroup1/task1
# ls /mnt/cgroup1/task1/
cgroup.clone_children    cgroup.procs             freezer.self_freezing    notify_on_release        
cgroup.event_control     freezer.parent_freezing  freezer.state            tasks 
# ping -D thomas-krenn.com >> freezer.txt &
[1] 2958
# echo 2958 > /mnt/cgroup1/task1/tasks
# cat /mnt/cgroup1/task1/tasks 
2958
# echo FROZEN > /mnt/cgroup1/task1/freezer.state
# tailf freezer.txt
# echo THAWED > /mnt/cgroup1/task1/freezer.state
# tailf freezer.txt
# kill 2958

blkio test

blkio setzt Limits für den Block IO Controller um. Im folgenden Beispiel wird der Durchsatz auf 1M/s limitiert:

# cgm create blkio bt
# cgm create blkio bt/test1
# fio ssd-test.fio &> ssd.out &
[2] 1859
# cgm movepid blkio bt/test1 1859
# cgm gettasks blkio bt/test1
method return sender=(null sender) -> dest=(null destination) reply_serial=1
   array [
      int32 1859
   ]
# cgm setvalue blkio bt/test1 blkio.throttle.read_bps_device "8:0 1048576"
# cgm getvalue blkio bt/test1 blkio.throttle.read_bps_device
string "8:0 1048576"
# iotop -o -n 3 -b|grep fio
 1914 be/4 root     1015.88 K/s    0.00 B/s  0.00 %  0.00 % fio ssd-test.fio
 1914 be/4 root     1013.04 K/s    0.00 B/s  0.00 %  0.00 % fio ssd-test.fio

LXC Metriken abfragen

LXC setzt beim Verwalten von Linux Container auf cgroups. Ressourcen können dadurch auf Container aufgeteilt werden.[6]

cgroups ermöglichen die Ressourcen-Aufteilung von Linux Containern. Grafik von Boden Russel, Folie 10.[6]

Während des Betriebs der Container können dann zugehörige Werte der cgroups abgefragt werden. Erste Werte liefert lxc-info:

lxc-info

Ein Aufruf von lxc-info zeigt den aktuellen Status zu einem Container:

# lxc-info -n ubuntu1
Name:           ubuntu1
State:          RUNNING
PID:            1645
IP:             10.0.3.119
CPU use:        1.58 seconds
BlkIO use:      22.67 MiB
Memory use:     31.48 MiB
KMem use:       0 bytes
Link:           veth0EP3QM
 TX bytes:      1.87 KiB
 RX bytes:      1.90 KiB
 Total bytes:   3.77 KiB

Folgende Informationen werden von lxc-info hier benutzt:[7]

Metrik Ursprung
CPU use lxc-cgroup -n ubuntu1 cpuacct.usage
BlkIO use lxc-cgroup -n ubuntu1 blkio.throttle.io_service_bytes
Memory use lxc-cgroup -n ubuntu1 memory.usage_in_bytes
KMem use lxc-cgroup -n ubuntu1 memory.kmem.usage_in_bytes
Link cat /sys/class/net/veth0EP3QM/statistics/*_bytes

Weitere Werte

Jedes Subsystem besitzt mehrere Parameter, die man abfragen kann. Interessant sind z.B.:[8]

  • memory.failcnt: Jene Anzahl, an der der Verbrauch an Memory den Schwellwert limit_in_bytes erreicht hat.
  • memory.stat: Detaillierte Memory Statistiken.[9]

Traditionelle Tools in Linux Containern

Traditionelle Kommandos werden über lxc-attach in den Containern ausgeführt:

# lxc-attach -n ubuntu1 -- top -n 1 -b
top - 10:12:47 up 58 min,  0 users,  load average: 0.00, 0.02, 0.05
Tasks:  18 total,   1 running,  17 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.4 us,  0.6 sy,  1.3 ni, 97.1 id,  0.4 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem:    501756 total,   445412 used,    56344 free,    67048 buffers
KiB Swap:   522236 total,        0 used,   522236 free.   231220 cached Mem
  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   33368   2724   1480 S  0.0  0.5   0:00.27 init
  191 root      20   0   19472    652    456 S  0.0  0.1   0:00.02 upstart-udev-br
  201 root      20   0   49268   1380    948 S  0.0  0.3   0:00.00 systemd-udevd

Problem dabei ist, dass ohne #LXCFS, die ausgegebenen Werte von /proc nicht zum Container passen. Eigentlich hätte folgender Container ein Limit von 256MB konfiguriert:

# grep limit_in_bytes /var/lib/lxc/ubuntu1/config
lxc.cgroup.memory.limit_in_bytes = 256M

Wird im Container selbst das free Programm aufgerufen, stimmt dieses Limit nicht mit den Werten überein:[10]

# lxc-attach -n ubuntu1
root@ubuntu1:~# free -m
             total       used       free     shared    buffers     cached
Mem:           489        457         32          5         81        241

Das Problem an den Werkzeugen ist, dass sie sich auf /proc Verzeichnis beziehen, welches aber nicht containerized wird.

LXCFS nimmt sich diesem Problem an, es kann Files mit den korrekten Werten über die /proc Files bind mounten.[11] Unter Ubuntu 15.04 kann lxcfs über die Ubuntu Repos installiert und konfiguriert werden.

Im ersten Schritt wird ein Hook in die Container Config eingefügt:

# vi /var/lib/lxc/ubuntu1/config
lxc.include = /usr/share/lxc/config/common.conf.d/00-lxcfs.conf

Beim starten im Debug Mode kann geprüft werden, ob der Hook ausgeführt wird:

# lxc-start -l debug -o lxc.log -d -n ubuntu1
# grep lxcfs lxc.log 
      lxc-start 1427909718.663 INFO     lxc_conf - conf.c:run_script_argv:345 - Executing script '/usr/share/lxcfs/lxc.mount.hook' for container 'ubuntu1', config section 'lxc'

Am Host selbst läuft lxcfs als Service und lxcfs ist nach /var/lib/lxcfs gemountet:

root@vivid:~# mount | grep lxcfs
lxcfs on /var/lib/lxcfs type fuse.lxcfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other)
root@vivid:~# service lxcfs status
  lxcfs.service - FUSE filesystem for LXC
   Loaded: loaded (/lib/systemd/system/lxcfs.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2015-03-31 08:25:32 CEST; 1h 3min ago
[...]

Prüft man die Uptime am Host und im Container, stimmt diese nun mit der tatsächlichen Uptime überein:

root@vivid:~# uptime 
 09:38:23 up  1:12,  2 users,  load average: 0.00, 0.01, 0.05
root@vivid:~# lxc-attach -n ubuntu1
root@ubuntu1:~# uptime 
 09:38:31 up 7 min,  0 users,  load average: 0.00, 0.01, 0.05
root@vivid:~# ls /var/lib/lxcfs/proc/
cpuinfo  meminfo  stat  uptime

Einzelnachweise

  1. Kernel Documentation cgroups.txt
  2. Resource Controllers in Linux Kernel (access.redhat.com)
  3. What's CGManager? (linuxcontainers.org)
  4. Ubuntu Server Guide cgroups manager (help.ubuntu.com)
  5. freezer-subsystem.txt (kernel.org)
  6. 6,0 6,1 Realizing Linux Containers (LXC) (slideshare.net)
  7. lxc_info.c (github.com)
  8. Control Groups Subsystems (docs.oracle.com)
  9. Ressource Mgmt Guide - memory (redhat.com)
  10. Memory inside Linux containers (fabiokung.com)
  11. What's LXCFS? (linuxcontainers.org)


Foto Georg Schönberger.jpg

Autor: Georg Schönberger

Georg Schönberger, Abteilung DevOps bei der XORTEX eBusiness GmbH, absolvierte an der FH OÖ am Campus Hagenberg sein Studium zum Bachelor Computer- und Mediensicherheit, Studium Master Sichere Informationssysteme. Seit 2015 ist Georg bei XORTEX beschäftigt und arbeitet sehr lösungsorientiert und hat keine Angst vor schwierigen Aufgaben. Zu seinen Hobbys zählt neben Linux auch Tennis, Klettern und Reisen.


Das könnte Sie auch interessieren

HA Cluster mit Linux Container basierend auf Heartbeat, Pacemaker, DRBD und LXC
Linux Containers LXC
LXD Grundbefehle