Diferencia entre revisiones de «Curso Python DGA 2011/sistemas/admin monitor»
(Página creada con '{{TEP}} == Administración y monitorización de sistemas con Python == === Administración de sistemas con Fabric === ==== ¿ Qué es Fabric ? ==== * Herramienta de línea d…') |
|||
(2 revisiones intermedias por el mismo usuario no mostrado) | |||
Línea 1: | Línea 1: | ||
− | |||
− | |||
== Administración y monitorización de sistemas con Python == | == Administración y monitorización de sistemas con Python == | ||
Línea 76: | Línea 74: | ||
==== Ejecución de operaciones en remoto ==== | ==== Ejecución de operaciones en remoto ==== | ||
+ | * Fabric se encarga de gestionar las conexiones con los hosts remotos sobre los que ejecutar comandos. | ||
+ | * Se hace cache de conexiones, fab las cierra al terminar. | ||
+ | * Fabric mantiene una cache de passwords, evitando tener que reintroducirlas constantemente. | ||
<source lang="python"> | <source lang="python"> | ||
# fabfile.py | # fabfile.py | ||
Línea 147: | Línea 148: | ||
</source> | </source> | ||
+ | |||
+ | ==== Ejecutando con sudo ==== | ||
+ | * Fabric también trae soporte para ejecutar comandos en máquinas remotas como "sudo" | ||
+ | <source lang="python"> | ||
+ | sudo("echo '192.168.0.2 importanthost' >> /etc/hosts") | ||
+ | </source> | ||
+ | |||
+ | |||
+ | ==== Manejando fallos ==== | ||
+ | * Cuando una tarea falla, fab aborta la ejecución del resto. Esto es muy útil si utilizamos Fabric como herramienta de builds y despliegue de nuestro proyecto. | ||
+ | <source lang="python"> | ||
+ | |||
+ | def test(): | ||
+ | #exec tests | ||
+ | pass | ||
+ | |||
+ | def pack(): | ||
+ | #package the project | ||
+ | |||
+ | def deploy(): | ||
+ | test() | ||
+ | pack() | ||
+ | #and then upload and deploy the actual project | ||
+ | </source> | ||
+ | |||
+ | * Si ejecutamos la tarea deploy, pero la ejecución de tests falla, no se realizará ni el empaquetado ni el despliegue. | ||
+ | * En algunos casos nos interesa manejar manualmente el error (usando warn_only=True): | ||
+ | |||
+ | <source lang="python"> | ||
+ | def exec_local(): | ||
+ | with settings(warn_only=True): | ||
+ | result = local('./inexistent_file', capture=True) | ||
+ | |||
+ | if result.failed and not confirm("inexistent_file doesn't exist. Continue?"): | ||
+ | abort("Aborting at user request.") | ||
+ | |||
+ | print("Successfully finished!") | ||
+ | </source> | ||
+ | |||
+ | {{Tip| Nótese el uso del context manager 'settings'. sirve para ejecutar acciones dentro de el con variables env.XXX de fabric modificadas. Fuera del bloque, env.warn_only es False. Ver http://docs.fabfile.org/en/1.2.1/usage/env.html para una lista completa de variables de configuración}} | ||
+ | |||
+ | ==== Context Managers ==== | ||
+ | |||
+ | Además del context manager ''settings'', que ya hemos visto antes, Fabric trae algunos muy útiles: | ||
+ | |||
+ | * '''cd(path)''' - Cambia el directorio de trabajo actual | ||
+ | <source lang="python"> | ||
+ | with cd('/var/www'): | ||
+ | run('ls') | ||
+ | </source> | ||
+ | |||
+ | ¿Y no es más fácil ejecutar lo siguiente?: | ||
+ | <source lang="python"> | ||
+ | run('/var/www') | ||
+ | run('ls') | ||
+ | </source> | ||
+ | No. '''Fabric no mantiene estado entre conexiones''', así que el comando 'ls' se ejecutará sobre el directorio de trabajo por defecto del usuario en el host | ||
+ | |||
+ | * '''lcd(path)''' - Equivalente a cd, pero para local. | ||
+ | * '''path(path, behavior='append')''' - Añade ''path'' a la variable de entorno PATH del sistema durante la ejecución de los comandos que encapsule. | ||
+ | * '''prefix(command)''' - Añade ''command'' como comando a ejecutar antes de cada comando invocado con '''run/sudo''', añadiéndoselo con && | ||
---- | ---- | ||
− | {{Tip| Aquí se ha descrito la funcionalidad "core" de Fabric. | + | {{Tip| Aquí se ha descrito buena parte de la funcionalidad "core" de Fabric, aunque provee más operaciones y context managers de los aquí descritos. Revisar la documentación de Fabric. Además, el paquete fabric.contrib trae varias utilidades comunes. Echad un vistazo a http://docs.fabfile.org/en/latest/index.html#contrib-api}} |
+ | |||
+ | |||
+ | === Monitorización de servidores y recolección de datos con Watchdog === | ||
+ | |||
+ | {{#widget:Slides}} | ||
+ | <div class="slides layout-regular template-default"> | ||
+ | <div class="slide"> | ||
+ | ==== ¿ Qué es Watchdog ? ==== | ||
+ | |||
+ | * Librería para facilitar la monitorización de servicios y notificar o realizar acciones en respuesta a incidentes. | ||
+ | * DSL propio para definir servicios y acciones | ||
+ | * Api simple y pequeña | ||
+ | |||
+ | ==== Instalación ==== | ||
+ | Por ahora no está disponible por defecto en distribuciones. Basta con descargar: | ||
+ | |||
+ | https://raw.github.com/sebastien/watchdog/master/Sources/watchdog.py | ||
+ | |||
+ | e incluirlo en el pythonpath. | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ==== Estructura del DSL ==== | ||
+ | [[Archivo:Watchdog dsl.png]] | ||
+ | * Los servicios se registran en el monitor | ||
+ | * Un servicio puede tener varias reglas, que se comprueban con una frecuencia de tiempo configurable | ||
+ | * Se pueden definir acciones cuando las reglas terminan con éxito o fracaso. | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ==== Reglas y acciones ==== | ||
+ | * Reglas: HTTP (prueba un servicio http), SystemHealth(comprueba que los niveles de cpu, disco, y memoria están por debajo de los niveles que establecemos), ProcessInfo, SystemInfo, Bandwith, Mem, Delta. | ||
+ | * Acciones: Log, Print, Restart (para reiniciar procesos), Email, XMPP, Incident (para ejectutar otras acciones en base a multiples fallos seguidos), ZMQPublish (para publicar mensajes en colas ZeroMQ). | ||
+ | |||
+ | * Podemos crear acciones y reglas personalizadas, extendiendo de Action y Rule. | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | ==== Ejemplos ==== | ||
+ | Ejemplo básico: | ||
+ | |||
+ | <source lang="python"> | ||
+ | from watchdog import * | ||
+ | |||
+ | Monitor( | ||
+ | Service( | ||
+ | name="apache-ensure-up", | ||
+ | monitor=( | ||
+ | HTTP( | ||
+ | GET="http://localhost:80/", | ||
+ | freq=Time.ms(500), | ||
+ | fail=[ | ||
+ | Print("Apache is down!!") | ||
+ | ] | ||
+ | ) | ||
+ | ) | ||
+ | ) | ||
+ | ).run() | ||
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | Enviando emails: | ||
+ | |||
+ | <source lang="python"> | ||
+ | HTTP( | ||
+ | GET="http://myservice.com/, | ||
+ | freq=Time.ms(500), | ||
+ | fail=[ | ||
+ | Email( | ||
+ | "admin@company.com", | ||
+ | "[Watchdog] Service unreachable", "Latency over 500ms", | ||
+ | "smtp.company.com", "username", "password" | ||
+ | ] | ||
+ | ) | ||
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | Incidentes, varios errores en un determinado tiempo: | ||
+ | <source lang="python"> | ||
+ | HTTP( | ||
+ | GET="http://myservice.com/, | ||
+ | freq=Time.ms(500), | ||
+ | fail=[ | ||
+ | Incident( | ||
+ | errors = 5, | ||
+ | during = Time.s(10) | ||
+ | actions = [ ... ] | ||
+ | ] | ||
+ | ) | ||
+ | </source> | ||
+ | </div> | ||
+ | <div class="slide"> | ||
+ | Monitorizando la salud del sistema: | ||
+ | <source lang="python"> | ||
+ | SystemInfo( | ||
+ | freq=Time.s(1), | ||
+ | success = ( | ||
+ | LogResult("myserver.system.mem=", extract=lambda r,_:r["memoryUsage"]), | ||
+ | LogResult("myserver.system.disk=", extract=lambda r,_:reduce(max,r["diskUsage"].values())), | ||
+ | LogResult("myserver.system.cpu=", extract=lambda r,_:r["cpuUsage"]), | ||
+ | ) | ||
+ | ), | ||
+ | Delta( | ||
+ | Bandwidth("eth0", freq=Time.s(1)), | ||
+ | extract = lambda v:v["total"]["bytes"]/1000.0/1000.0, | ||
+ | success = [LogResult("myserver.system.eth0.sent=")] | ||
+ | ), | ||
+ | SystemHealth( | ||
+ | cpu=0.90, disk=0.90, mem=0.90, | ||
+ | freq=Time.s(60), | ||
+ | fail=[Print("Health compromised!!")] | ||
+ | ) | ||
+ | </source> | ||
+ | </div> |
Última revisión de 06:17 24 nov 2011
Contenido
Administración y monitorización de sistemas con Python
Administración de sistemas con Fabric
¿ Qué es Fabric ?
- Herramienta de línea de comandos y librería para facilitar la administración de sistemas y despliegue de aplicaciones a través de SSH.
- Los scripts en fabric son python usando el api que provee.
- Permite ejecutar comandos shell localmente o remotamente, así como subir y bajar ficheros de sistemas remotos.
- Ejecuta mismas tareas en múltiples hosts definidos.
- Es capaz de manejar las peticiones de input por parte de los programas ejecutados a través de la shell remota (ej: petición de passwords)
Instalación
- Usaremos la última release 1.x, a día de hoy 1.2.1
- Ubuntu 11.04 (natty) trae fabric 0.9.3, aunque la próxima oneiric ya saldrá con una 1.0.
Por tanto instalaremos la última release de https://github.com/fabric/fabric/downloads.
Necesitaremos:
- tener setuptools instalada
- python-paramiko - nos sirve el paquete que trae ubuntu
Una vez descargada la release y cumplidas las dependencias:
python setup.py install
Herramienta fab y tareas
Fabric trae la herramienta fab, con la que podemos ejecutar funciones (tareas) que escribamos en fabfile.py
# fabfile.py def hello(name="world"): print("Hello {0}".format(name))
$ fab hello Hello world Done.
- Se pueden pasar parámetros:
$ fab hello:luis
Hello luis
Done.
$ fab hello:name=luis
Hello luis
Done.
- Podemos hacer tareas que llamen a tareas, puesto que las tareas son funciones python.
Ejecución de operaciones en local
# fabfile.py from fabric.api import local def sysinfo(): cpu_info = local("cat /proc/stat") mem_info = local("cat /proc/meminfo") print(cpu_info) print(mem_info)
Ejecución de operaciones en remoto
- Fabric se encarga de gestionar las conexiones con los hosts remotos sobre los que ejecutar comandos.
- Se hace cache de conexiones, fab las cierra al terminar.
- Fabric mantiene una cache de passwords, evitando tener que reintroducirlas constantemente.
# fabfile.py from fabric.api import local def sysinfo(): cpu_info = run("cat /proc/stat") mem_info = run("cat /proc/meminfo") print(cpu_info) print(mem_info)
- Si ejecutamos esta operación, dado que no hemos definido ningún host, fabric nos pedirá donde queremos ejecutar las operaciones (user@host)
$ fab sysinfo No hosts found. Please specify (single) host string for connection:
- Podemos definir los hosts donde ejecutar las operaciones de forma global al script:
env.hosts = ['192.168.0.11', '192.168.0.20', 'my_server']
Aunque esto asumirá que que el usuario con el que nos autenticamos es el mismo usuario que ejecuta el script.
- Podemos poner el usuario con el que se ejecutará:
env.hosts = ['luis@192.168.0.11', 'root@192.168.0.20', 'my_server']
- Podemos especificar hosts para una tarea en concreto:
@hosts('user1@logserver1', 'logserver') def diskusage(): disk_usage = run("df -h /dev/sda1")
- ... o pasar por línea de comandos los hosts
$ fab diskusage --hosts=192.168.0.11
Roles en Fabric
Se pueden agrupar hosts de forma que se puedan ejecutar tareas para un determinado grupo, usando @roles
env.roledefs.update({ 'locales': ['192.168.1.1', '192.168.1.2'], 'logservers': ['logserver1, logserver2'] }) @roles('logservers') def diskusage(): pass
- También se puede ejecutar sobre un rol en concreto desde línea de comandos:
$ fab -R logservers diskusage
Subiendo y bajando ficheros
put('bin/project.zip', '/tmp/project.zip') put('*.py', 'cgi-bin/') put('index.html', 'index.html', mode=0755) get('/path/to/remote_file.txt')
Ejecutando con sudo
- Fabric también trae soporte para ejecutar comandos en máquinas remotas como "sudo"
sudo("echo '192.168.0.2 importanthost' >> /etc/hosts")
Manejando fallos
- Cuando una tarea falla, fab aborta la ejecución del resto. Esto es muy útil si utilizamos Fabric como herramienta de builds y despliegue de nuestro proyecto.
def test(): #exec tests pass def pack(): #package the project def deploy(): test() pack() #and then upload and deploy the actual project
- Si ejecutamos la tarea deploy, pero la ejecución de tests falla, no se realizará ni el empaquetado ni el despliegue.
- En algunos casos nos interesa manejar manualmente el error (usando warn_only=True):
def exec_local(): with settings(warn_only=True): result = local('./inexistent_file', capture=True) if result.failed and not confirm("inexistent_file doesn't exist. Continue?"): abort("Aborting at user request.") print("Successfully finished!")
Context Managers
Además del context manager settings, que ya hemos visto antes, Fabric trae algunos muy útiles:
- cd(path) - Cambia el directorio de trabajo actual
with cd('/var/www'): run('ls')
¿Y no es más fácil ejecutar lo siguiente?:
run('/var/www') run('ls')
No. Fabric no mantiene estado entre conexiones, así que el comando 'ls' se ejecutará sobre el directorio de trabajo por defecto del usuario en el host
- lcd(path) - Equivalente a cd, pero para local.
- path(path, behavior='append') - Añade path a la variable de entorno PATH del sistema durante la ejecución de los comandos que encapsule.
- prefix(command) - Añade command como comando a ejecutar antes de cada comando invocado con run/sudo, añadiéndoselo con &&