Gestionar Contendores Docker con CGroups

El mes pasado hablé en ApacheCon sobre Cgroups. Parece que muy pocos usuarios de Linux (incluyendo mi mismo hasta hace poco) están familiarizados con Cgroups y su poder. Esto es una lástima, porque Cgroups muy poderosos, y permiten asignar recursos en sus servidores de una manera mucho más detallada que en cualquier otra herramienta disponible en el kit de herramientas de Linux. Por otra parte, está programado directamente en el kernel y viene fuera de la caja con la mayoría de las distribuciones de Linux.

En este artículo voy a cubrir cómo utilizar Cgroups con Docker como una especie de seguimiento de la otra platica que di en el Docker Meetup en Austin, Texas.

Este artículo no requiere ningún conocimiento básico de Cgroups. Si es completamente nuevo a Cgroups, le recomiendo leer mi dispositivo de ApacheCon, así como los recursos al final. No se preocupen, no tocaremos un nivel de mucha profundidad técnica. Si nadamas le echo ojo al conjunto de positivis, usted debería ser capaz de aprender los conceptos básicos.

Docker y Cgroups

Docker viene con dos controladores diferentes: LXC y libcontainer. LXC es el controlador legado, mientras libcontainer es el controlador nuevo y predeterminado. En la mayoría de los casos, libcontainer es el controlador preferido, ya que es donde sucede la innovación (por ejemplo docker exec no funciona con el controlador LXC).

Sin embargo, es importante tener en cuenta que hay dos controladores diferentes, ya que no todas las capacidades de Cgroup han sido portados a libcontainer todavía (o por lo menos expuesto a Docker). Al utilizar el controlador LXC, sólo tiene que pasar los argumentos de LXC directamente, mientras que con libcontainer son argumentos explícitos de política de Cgroup expuestos a Docker. Tendrá que establecer explícitamente un controlador al iniciar el daemon de Docker, por lo que no se puede ejecutar dos controladores simultáneamente.

Aquí está un ejemplo de cómo lo puede comprobar::

[bash light=»true»] # Con el controlador LXC
$ docker run -d –name=’lxc_test’ \
–lxc-conf="lxc.cgroup.cpu.shares=50" \
busybox

# Con el controlador libcontainer
$ docker run -d –name=’libcontainer_test’ \
–cpu-shares=50 \
busybox
[/bash]

He aquí un resumen de algunas de las características de Cgroup y cómo se desplazan entre los dos controladores:

Característica Libcontainer LXC
Cuota Relativa de CPU -c, –cpu-shares –lxc-conf=»lxc.cgroup.cpu.shares»
Acoplado a un núcleo de CPU –cpuset-cpus –lxc-conf=»lxc.cgroup.cpuset.cpus»
Límite de memoria -m, –memory –lxc-conf=»lxc.cgroup.cpuset.mems»

LXC

Si desea utilizar el controlador de LXC para Docker, primero deberá activarlo. El método para hacer esto variará en función de la distribución de Linux, pero aquí están las instrucciones sobre cómo activar el controlador LXC en Ubuntu 14.04.

Como se mencionó anteriormente, está cediendo una serie de características al hacer esto. Por lo tanto, a menos que realmente necesita la funcionalidad que aún no se ha expuesto en Docker mediante libcontainer, debería seguir con el controlador predeterminado.

Algunas políticas de Cgroup útiles, que aún no se han expuesto en libcontainer incluyen I/O throttling (cubierto en la presentación), que puede ser muy útil para ciertas aplicaciones.

Si usted ha decidido utilizar el controlador LXC, es fácil el añadir nuevos argumentos. Todo lo que necesita hacer es añadir el argumento --lxc-conf y agregar la política de Cgroup que desea establecer.

Libcontainer

Como se puede ver en la tabla anterior, las políticas básicas de Cgroup ya están expuestas en la versión actual de Docker (1.6 al escribir).

El uso de estas políticas es muy simple. Si por ejemplo quiere asegurar un container de Docker al primer núcleo de CPU, usted anexa --cpuset-cpus=0 a su comando de docker run.

También puede utilizar el argumento --cgroup-parent con libcontainer y establecer manualmente mas limitaciones de recursos más granulares. A continuación, los asignarla a ese grupo usando argumentos.

Demostración: Docker con Cgroupsps

En el screencast a continuación, vamos a utilizar dos contenedores de Docker (‘low_prio’ y ‘high_prio’). Usamos el contenedor ‘busybox’ base y ejecutamo md5sum /dev/urandom para simular un proceso CPU de alta utilización. Por defecto, esta consumiría todos los recursos de CPU disponibles. Sin embargo, vamos a aplicar dos políticas de Cgroup para gestionar los recursos. Primero usamos ‘cpuset.cpus’ para acoplar los contenedores al mismo núcleo de CPU (núcleo 0).

A continuación, utilizamo ‘cpu.shares’ para asignar un recurso de CPU relativo. Le damos el contenedor ‘low_prio’ cun valor de 20 y el 80% de la CPU se asignará al contenedor ‘high_prio’. Esto significa que el 20% de la CPU se asigna al contenedor ‘low_prio’, y el 80% de la CPU se asignará al contenedor’high_prio’. Tenga en cuenta que la participación relativa es una escala arbitraria (podríamos igual haber usado 2 y 8 como valores).

Después de que hemos demostrado que el manejo de los recursos de hecho funciona, lanzamos el mismo conjunto de contenedores sin ningún tipo de políticas de Cgroup para ver cómo se comportan.

Como referencia, aquí están los comandos que se utilizan para poner en marcha los contenedores.

[bash light=»true»] $ docker run -d \
–name=’low_prio’ \
–cpuset-cpus=0 \
–cpu-shares=20 \
busybox md5sum /dev/urandom
$ docker run -d \
–name=’high_prio’ \
–cpuset-cpus=0 \
–cpu-shares=80 \
busybox md5sum /dev/urandom
[/bash]

Resumen

Si administra varios contenedores de Docker en el mismo servidor, el usar Cgroups para gestionar los recursos entre los contenedores tiene mucho sentido. Por ejemplo, tal vez usted tiene algunas tareas de procesamiento de fondo que se ejecuta en un contenedor, y otro contenedor sirviendo el contenido del usuario. En ese caso, puede utilizar sus nuevos conocimientos para asegurar el dar prioridad a los contenedores al frente del usuario antes que los de las tareas al fondo.

About Patrick Baillie

Patrick is co-founder of CloudSigma, and comes from a career working in Investment Banking Technology, as well as having previously ran his own business.