lunes, 7 de diciembre de 2015

Tutorial Request Tracker 4.4

Request Tracker es una muy buena herramienta que se puede adaptar a nuestras necesidades, pero su configuración básica (como viene con la instalación) requiere bastante trabajo para adaptarlo a cada realidad y la documentación disponible no es muy buena y es en muchos casos para versiones antiguas. En este tutorial voy a partir con la instalación y luego continuaré realizando varias personalizaciones para lograr una integración con la herramienta de monitoreo Prometheus (prometheus.io) a modo de ejemplo.
La versión 4.4 aún no es liberada en su versión estable, por lo que este tutorial está hecho con la versión RC2.
https://www.bestpractical.com/docs/rt/4.4/README.html 
Los siguientes pasos fueron probados en Ubuntu 14.04

Instalación


Requisitos

Instalar los siguientes paquetes:
apt-get install -y perl mariadb-server apache2 libapache2-mod-fastcgi liblwp-protocol-https-perl libcrypt-ssleay-perl libxml-rss-perl libperlio-eol-perl libfile-which-perl libgnupg-interface-perl libconvert-color-perl libfcgi-procmanager-perl libfcgi-perl libmime-types-perl libcss-squish-perl libnet-cidr-perl libmodule-refresh-perl libdata-guid-perl libjson-perl libemail-address-list-perl libplack-perl libencode-perl libdata-ical-perl libdevel-globaldestruction-perl libtext-password-pronounceable-perl libhtml-formattext-withlinks-perl libtext-wrapper-perl libregexp-ipv6-perl libcrypt-x509-perl libstring-shellquote-perl libdatetime-format-natural-perl libcrypt-eksblowfish-perl libdate-manip-perl liblocale-maketext-fuzzy-perl libhtml-formattext-withlinks-andtables-perl libtext-template-perl libhtml-scrubber-perl libencode-perl libdbix-searchbuilder-perl liblocale-maketext-lexicon-perl libtext-wikiformat-perl liblog-dispatch-perl libapache-session-perl libtree-simple-perl librole-basic-perl libipc-run3-perl libcgi-psgi-perl libhtml-mason-perl libhtml-quoted-perl libuniversal-require-perl libregexp-common-net-cidr-perl libhtml-mason-psgihandler-perl libregexp-common-perl libmodule-versions-report-perl libhtml-quoted-perl libdate-extract-perl libsymbol-global-name-perl libtext-quoted-perl libgd-graph-perl libgd-text-perl libnet-ldap-perl libnet-ldap-server-perl graphviz libgraphviz-perl libscope-upper-perl libipc-run-perl libdata-pageset-perl libjavascript-minifier-xs-perl libencode-perl libhtml-rewriteattributes-perl libcss-minifier-xs-perl sendmail

Espacio mínimo en disco:
200MB en /opt

Instalación

Por ahora está disponible el Release Candidate 2:
wget https://download.bestpractical.com/pub/rt/devel/rt-4.4.0rc2.tar.gz
tar -zxvf rt-4.4.0rc2.tar.gz
cd rt-4.4.0rc2/
./configure --enable-graphviz --enable-gd
/usr/bin/perl -MCPAN -e shell
make fixdeps
make install

Configuración inicial

/opt/rt4/sbin/rt-server --port 8080
Navegar a la página y seguir instrucciones. Asumiendo que nuestro servidor de instalación se llama rt.example.com, navegamos a http://rt.example.com:8080
Al finalizar la configuración, damos ctrl-C al comando para terminar el servidor. Ahora lo vamos a configurar para subir con apache.

Configurar apache

Creamos un archivo con la configuración del sitio:
> cat /etc/apache2/sites-available/001-rt4.conf
# Tell FastCGI to put its temporary files somewhere sane; this may
# be necessary if your distribution doesn't already set it
#FastCgiIpcDir /tmp

FastCgiServer /opt/rt4/sbin/rt-server.fcgi -processes 5 -idle-timeout 300

<VirtualHost rt.lagos.cl>
    ### Optional apache logs for RT
    # Ensure that your log rotation scripts know about these files
    ErrorLog /opt/rt4/var/log/apache2.error
    TransferLog /opt/rt4/var/log/apache2.access
    LogLevel debug

    AddDefaultCharset UTF-8

    ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/

    DocumentRoot "/opt/rt4/share/html"
    <Location />
        Require all granted
        Options +ExecCGI
        AddHandler fastcgi-script fcgi
    </Location>
</VirtualHost>

Ahora reemplazamos el sitio por defecto que viene con la instalación de apache por RT4:
cd /etc/apache2/sites-enabled
rm 000-default.conf
ln -s ../sites-available/001-rt4.conf
service apache2 restart

Configurar correo

Para configurar sendmail, editar en archivo /etc/mail/sendmail.mc las líneas:
DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp')dnl
define(`confCONNECTION_RATE_THROTTLE', `-1')dnl
y eliminar línea:
define(`confCONNECTION_RATE_WINDOW_SIZE',`10m')dnl
Luego ejecutar:
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf

En archivo /etc/aliases agregar:
<casilla correspondencia>:         "|/opt/rt4/bin/rt-mailgate --queue <cola> --action correspond --url <ubicación de rt>"
<casilla comentarios>: "|/opt/rt4/bin/rt-mailgate --queue <cola> --action comment --url <ubicación de rt>"

Por ejemplo:
rt:          "|/opt/rt4/bin/rt-mailgate --queue 'Reportes de Incidente' --action correspond --url http://rt.example.com/"
rt-comment:  "|/opt/rt4/bin/rt-mailgate --queue 'Reportes de Incidente' --action comment --url http://rt.example.com/"
rtinc:     "|/opt/rt4/bin/rt-mailgate --queue 'Incidentes' --action correspond --url http://rt.example.com/"
rtinc-com: "|/opt/rt4/bin/rt-mailgate --queue 'Incidentes' --action comment --url http://rt.example.com/"

Y reiniciar sendmail:
service sendmail restart

En el ejemplo anterior, los usuarios se comunican con rt a la casilla rt@rt.example.com y los comentarios privados del personal se envían a rt-comment@rt.example.com

Extensiones

Instalar la siguiente extensión siguiendo sus instrucciones de instalación:
En CPAN hay muchas extensiones para Request Tracker. Estas son algunas de las que encuentro más interesantes, pero no es necesario instalar para este tutorial:

Configuración

Usuarios

Para efectos de este tutorial, crear los siguientes usuarios (Admin -> Users -> Create) y a todos ,menos a "user", activarles la casilla "Let this user be granted rights (Privileged)". Todos deben tener activada la casilla "Let this user access RT".
  • agent: Service Desk Analyst
  • resolutor: First/second/third line analyst
  • manager: Service Desk Manager (no necesario crear de inmediato)
  • user: Usuario de los servicios TI
  • mon: usuario creado para que el monitoreo gestione sus tickets
Lo ideal es a cada usuario asignarle una casilla de correo válida en el ambiente en que estamos trabajando. Como laboratorio, yo usé Zentyal (http://www.zentyal.org/) para armar un dominio de "juguete" y configuré en él el DNS, los usuarios y las casillas de correo (incluye un software de webmail), pero su instalación y configuración queda fuera del alcance de este tutorial.

Grupos

Crear los siguientes grupos y asignarles los usuarios correspondientes:
  • ServiceDeskManager (no necesario crear de inmediato)
    • manager
  • ServiceDeskAnalyst
    • agent
  • IncidentAnalyst
    • resolutor
    • mon

Escenario 2

Usando como base el post anterior, los pasos para configurar Request Tracker para que cumpla con el escenario 2 son:
  • Renombrar cola General a “Reportes de Incidente”
  • Crear cola “Incidentes”
  • Otorgar los siguientes permisos al grupo Everyone en cola “Reporte de Incidente”:
    • Comment on Ticket
    • Create Tickets
    • Reply to Tickets
    • View Queue
  • Otorgar el siguiente permiso al grupo Requestor:
    • View Ticket Summaries
  • Otorgar los siguientes permisos al grupo ServiceDeskAnalyst en colas Incidentes y Reportes de Incidente y a IncidentAnalyst en cola Incidentes: 
    • Comment on Ticket
    • Create Tickets
    • Reply to Tickets
    • View Queue
    • View Ticket Summaries
    • View Ticket Private Commentary
    • View custom field values
    • Sign up as a ticket Requestor or ticket or queue Cc
    • Sign up as a ticket or queue AdminCc
    • Own Tickets
    • Modify Tickets
  • Crear los siguientes campos custom en cola Incidentes (adaptar según preferencias):
    • Descripción (Fill in one text area)
    • Categoría (Select one value)
      • Monitoreo
      • Backups
      • Servidor
      • Red
      • Storage
      • Base de Datos
      • Servicio de Directorio
      • Microinformática
      • Middleware
      • Internet
      • Data Center
    • Urgencia (Select one value)
      • Alta
      • Media
      • Baja
    • Impacto (Select one value)
      • Alto
      • Medio
      • Bajo
    • Reportado por (Enter one value)
    • Método de notificación (Select one value)
      • Teléfono
      • Email
      • Autoatención
      • Automático
  • Agregar permisos para ver y modificar los campos custom al grupo ServiceDeskAnalyst y al rol Owner
  • Asignar scrip “On Resolve, Resolve Children” a cola Incidentes (ver detalle de scrip en sección correspondiente más abajo).
Con esta configuración, "user" puede enviar un correo a rt@example.com lo que gatillará la creación automática de un ticket en la cola "Reportes de Incidente". RT le enviará un correo a "user" avisándole que fue recibido su correo y el número de ticket creado. El analista ("resolutor") aún no puede ver el ticket, ya que no tiene permisos para esa cola, por lo que "agent", al recibir el ticket, deberá revisar si hay algún incidente ya creado que esté asociado a este nuevo ticket. Si ya hay, asocia los tickets dejando al incidente como padre y al reporte de incidente como hijo. Si no había incidente creado, se crea uno nuevo y se deja al incidente como padre y al reporte de incidente como hijo. Por lo tanto, podríamos quedar con un incidente que tiene varios hijos (reportes de incidente).
Ahora "resolutor" ve el ticket en la cola Incidente, por lo que puede trabajar en su solución y cerrarlo. Al resolver el Incidente, entra en acción el scrip asignado cerrando todos los tickets de la cola "Reportes de Incidente" y notificando a los usuarios de su cierre.

Escenario 4

Me saltaré el escenario 3, pasando directamente al escenario 4. Para efectos del tutorial, usaré Prometheus como sistema de monitoreo, pero evitaré extenderme en la explicación del uso de Prometheus, ya que queda fuera del alcance de este tutorial.
En la sección de configuración del correo, se definieron 4 alias: rt, rt-comment, rtinc y rtinc-com.
La primera casilla es para ser usada por los usuarios: ellos envían correos a esa casilla para abrir y hacer seguimiento de tickets (cuando responden a un correo con el subject del correo recibido de confirmación de creación de ticket, el correo se suma al ticket como comentario). La segunda y cuarta casillas son para comentarios internos del staff del Service Desk. Lo que llegue por esa casilla quedará registrado en Request Tracker, pero no será visible por el usuario final. La tercera casilla, es para recibir los correos del monitoreo, los que gatillarán automáticamente la generación de un ticket en la cola "Incidentes", saltándose el paso de crear un ticket en "Reportes de Incidente".
Tomando como base lo que ya hicimos para el escenario 2:
  • Modificar en RT la configuración de la cola Incidentes para que las direcciones “Reply Address” y “Comment Address” apunten a rtinc@rt.example.com y rtinc-com@rt.example.com)
  • Se debe configurar un scrip en la cola Incidentes que cierre los tickets al recibir un ok desde Pometheus. Ver Scrip “Update Prometheus Tickets” (este scrip adicionalmente une los tickets duplicados).

Por el lado de Prometheus:


  • En este ejemplo se usó la siguiente configuración en prometheus, donde se aprovechó la integración con consul para service discovery:
- job_name: 'node_exporter' consul_sd_configs: - server: 'consul.example.com:8500' services: ['node_exporter'] relabel_configs: - source_labels: ['__meta_consul_service'] regex: '(.*)' target_label: 'job' replacement: '$1' - source_labels: ['__meta_consul_node'] regex: '(.*)' target_label: 'instance' replacement: '$1' - source_labels: ['__meta_consul_tags'] regex: ',(production|canary),' target_label: 'group' replacement: '$1'
  • Para las reglas en prometheus:
> cat node.rules IF avg(node_filesystem_avail{job='node',fstype='ext4'} / node_filesystem_size{job='node',fstype='ext4'} * 100) BY (instance,mountpoint) < 15
ALERT LowDiskSpace
SUMMARY "Service Alert: {{$labels.instance}}/Filesystem {{$labels.mountpoint}} is WARNING"
DESCRIPTION "Descripción: El filesystem {{$labels.mountpoint}} del nodo {{$labels.instance}} se esta quedando sin espacio (espacio libre: {{$value}}%)&Categoría: Servidor&Urgencia: Baja&Impacto: Bajo&Reportado por: monitoreo&Método de notificación: Automático"

  • Usar la siguiente configuración para alertmanager (esto es para versión v0.0.4 que al parecer será deprecada pronto):

> cat alertmanager.conf 
notification_config {
    name: "node_notification"
    email_config {
        email: "rtinc@rt.example.com"
send_resolved: true
    }
}
aggregation_rule {
    repeat_rate_seconds: 3600
    notification_config_name: "node_notification"
}
  • Yo tengo el Alert Manager corriendo en un container docker:
    • run -d -p 9093:9093 --name prom_alert2 -v /docker/prometheus/config/alertmanager.conf:/alertmanager.conf prom/alertmanager -config.file=/alertmanager.conf -notification.smtp.smarthost=mail.example.com:25 -alerts.min-refresh-period=0m30s -notification.smtp.sender=mon@example.com
Con esta configuración, si un nodo monitoreado por Prometheus gatilla una alarma de espacio en disco, se generará automáticamente un ticket en la cola "Incidentes". Si un usuario reporta un incidente relacionado al llenado de ese disco, el agente asociará el ticket de la cola Incidente creado por Prometheus como padre del ticket de Reporte de Incidente. El resolutor verá el ticket creado por Prometheus y trabajará en su solución. Una vez que se limpie la alarma, Prometheus enviará un correo indicando que la alerta está resuelta. Esto provocará en Request Tracker que se creé un nuevo ticket y se gatille el scrip "Update Prometheus Tickets". Este scrip buscará todos los tickets asociados a esa alerta y los unirá para posteriormente cerrar el ticket. Al resolver el ticket, se resolverán también todos los tickets hijos (Reportes de Incidente).

Escenario 5

Para no seguir alargando el tutorial, solo haré una parte del escenario 5: extraer datos para la generación del ticket desde el contenido del correo de alerta de Prometheus. Para ello usaré la extensión RT::Extension::ExtractCustomFieldValues.

  • Crear el siguiente template:

Name: PrometheusFieldScanner
Description: Busca Custom Fields en los correos de Prometheus
Type: Perl
Content:
Descripción|Body|Descripción:\s+([^&]+)
Categoría|Body|Categoría:\s+([^&]+)
Urgencia|Body|Urgencia:\s+([^&]+)
Impacto|Body|Impacto:\s+([^&]+)
Reportado por|Body|Reportado por:\s+([^&]+)
Método de notificación|Body|Método de notificación:\s+([^\n]+)

  • Crear el siguiente scrip en cola Incidente (o donde lleguen los correos de Prometheus):

Description: Prometheus Field Scanner
Condition: On Create
Action: Extract Custom Field Values With Code in Template
Template: PrometheusFieldScanner

Y eso es todo. Ahora Request Tracker llenará automáticamente los campos custom con la información que extraiga del correo recibido desde Prometheus.

Scrips

Name: On Resolve, Resolve Children

Condition: On Resolve
Action: User Defined
Template: blank
Custom Condition: “”
Custom action preparation code:
return 1;
Custom action commit code:
my $ticket = $self->TicketObj;
my $id = $ticket->Id;
my $members = RT::Tickets->new( $ticket->CurrentUser );

$members->LimitQueue(VALUE => 'Reportes de Incidente');
$members->LimitToActiveStatus();
$members->LimitLinkedTo(TYPE => 'MemberOf', TARGET => $ticket->id);

while ( my $member = $members->Next ) {
  my $set_to = "resolved";
  next if $member->Status eq $set_to;
  my ($res, $msg) = $member->SetStatus( $set_to );
  RT->Logger->info( "Couldn't resolve ticket: $msg" ) unless $res;
}

return 1;

Name: Update Prometheus Tickets

Condition: On Create
Action: User Defined
Template: blank
Custom Condition: “”
Custom action preparation code:
return 1;
Custom action commit code:
$RT::Logger->info("Update Prometheus Tickets: Inicio scrip");
my $attachment = $self->TransactionObj->Attachments->First;
return 1 unless $attachment;

my $new_ticket    = $self->TicketObj;
my $new_ticket_id = $new_ticket->id;

my $subject = $attachment->GetHeader('Subject');
return unless $subject;

if ( my ( $type, $category, $host, $port, $problem_type, $problem_severity ) =
        $subject =~ m{\[(ALERT|RESOLVED)\]
            \s+ ([^:]+):
            \s+Service\s+Alert:
            \s+([^/:]+):(\d+)/?(.*)
            \s+ is \s+(\w+)}ix
      )
    {
        $RT::Logger->info(
"Extracted type, category, host, problem_type and problem_severity from
subject with values $type, $category, $host, $problem_type and $problem_severity"
        );
        my $tickets = RT::Tickets->new( $self->CurrentUser );
        $tickets->LimitQueue( VALUE => $new_ticket->Queue );
        my $subject = "$category: Service Alert: $host:$port/$problem_type";
        $tickets->LimitSubject(
            VALUE => $subject,
            OPERATOR => 'LIKE',
        );
        my @active = RT::Queue->ActiveStatusArray();
        for my $active (@active) {
            $tickets->LimitStatus(
                VALUE    => $active,
                OPERATOR => '=',
            );
        }
        my $resolved = 'resolved';

        my $merge_type = -1;
        my $merged_ticket;

        $tickets->OrderBy(
            FIELD => 'Created',
            ORDER => $merge_type > 0 ? 'DESC' : 'ASC',
        );
        $merged_ticket = $tickets->Next;

        while ( my $ticket = $tickets->Next ) {
            $RT::Logger->info("Update Prometheus Tickets: Voy a unir los tickets " . $ticket->id . " y " . $merged_ticket->id);
            my ( $ret, $msg ) = $ticket->MergeInto( $merged_ticket->id );
            if ( !$ret ) {
                $RT::Logger->error( 'failed to merge ticket '
                      . $ticket->id
                      . " into "
                      . $merged_ticket->id
                      . ": $msg" );
            }
        }

        if ( uc $type eq 'RESOLVED' ) {
            if ( not $merged_ticket or not $merged_ticket->id ) {
                $RT::Logger->error( 'Recovery ticket with no initial ticket: $subject' );
                $merged_ticket = $new_ticket;
            }
            $RT::Logger->info("Update Prometheus Tickets: Voy a cerrar el ticket " . $merged_ticket->id);
            my ( $ret, $msg ) = $merged_ticket->SetStatus($resolved);
            if ( !$ret ) {
                $RT::Logger->error( 'failed to resolve ticket '
                      . $merged_ticket->id
                      . ":$msg" );
            }
        }
    }

return 1;

PD

Maldito Blogger. No logro dar buen formato a los posts

viernes, 27 de noviembre de 2015

Gestión de Incidentes en la práctica. Parte 1

Cuando queremos implementar las mejores prácticas de ITIL nos podemos topar en principio con la idea de que significa más burocracia y que en lugar de acelerar los tiempos de resolución de incidentes, los aumentaremos. A eso se añade la posible resistencia de los equipos de trabajo a registrar metódicamente la información de los incidentes. También si damos un margen para que las personas tomen decisiones con respecto al registro de incidentes, nos encontraremos con información que dependerá de la persona que lo registró, afectando a las estadísticas. Esto se puede resolver teniendo un chequeo posterior de la información de los incidentes, pero significa aumentar aún más la carga de trabajo asociada a la implementación de gestión de incidentes según recomienda ITIL.
El manejo de incidentes se puede implementar de manera escalada, consiguiendo cada vez una mejor gestión y reportes más exactos de los eventos. Progresar en la implementación de los siguientes escenarios permitirá seguir, de manera eficiente y en gran parte automatizada, las mejores prácticas definidas por ITIL. Además, al automatizar el proceso, eliminamos el riesgo de que la información registrada dependa de la persona que ingresó el ticket. En este post quedarán 5 escenarios, pero aún quedando bastante margen para seguir mejorando el proceso.

Escenario 1


  1. Usuario llama a mesa de ayuda o le envía un correo, donde el analista de service desk genera un ticket de tipo “Incidente”.
  2. El sistema envía un correo automático al usuario con el número de ticket creado.
  3. Agente revisa si ya existía un ticket de tipo “Incidente” para el reporte. Si ya existía, asocia el nuevo ticket con el ya existente. 
  4. Resolutor (analista de primera, segunda o tercera línea) toma el o los tickets de tipo “Incidente”.
  5. Al resolver el ticket, se resuelven manualmente todos los tickets de tipo “Incidente” asociados y se notifica automáticamente a los usuarios.

Problemas principales:

  • La mayor parte del proceso es manual, por lo que los tiempos de inicio y fin de incidente no son confiables y deben ser ajustados posteriormente en base a diversos criterios (revisando monitoreos, logs, emails, etc).
  • Pueden quedar registrados múltiples tickets para un mismo incidente (varios usuarios reportando el mismo problema), lo que dificulta el cálculo de SLA por servicio.

Posibles mejoras:

  • Permitir que el envío de correo a una casilla de email genere automáticamente un Reporte de Incidente.
  • Dividir los tickets en dos “colas”: una para “Incidente” y otra para “Reporte de Incidente”. De esta manera cada ticket en la cola "Incidente" representará a un incidente en particular y puede tener asociados varios "Reporte de Incidente" de usuarios distintos.

Escenario 2


  1. Usuario envía correo a mesa de ayuda, donde se genera automáticamente un ticket de tipo “Reporte de Incidente”. Alternativamente, usuario crea el ticket de tipo “Reporte de Incidente” ingresando a la opción de autoatención del sistema. Se mantiene opción de ingresar un reporte de incidente llamando al Service Desk.
  2. El sistema envía un correo automático al usuario con el número de ticket creado.
  3. Agente revisa si ya existe un ticket de tipo “Incidente” para el reporte. Si ya existe, le asocia el nuevo ticket. Si no existe, crea un nuevo ticket de tipo “Incidente” a partir del “Reporte de Incidente”.
  4. Resolutor toma el ticket de tipo “Incidente”.
  5. Al resolver el ticket de tipo "Incidente", se resuelven automáticamente todos los tickets de tipo “Reporte de Incidente” y se notifica automáticamente a los usuarios.

Problemas principales:
  • Manejo reactivo de incidentes: depende del reporte de un usuario.
  • Las horas de inicio y fin del incidente no son confiables, ya que el inicio depende del reporte del usuario (o del agente que detectó el problema a través de algún monitoreo) y el fin del incidente es según lo reportado por el agente, pero sujeto a validación por parte del usuario.
Posibles mejoras:

  • Implementar monitoreo que genere tickets de tipo Incidente automáticamente al detectar una falla en la plataforma.

Escenario 3


  1. Monitoreo detecta falla en un componente.
  2. Monitoreo genera una alerta que gatilla la generación automática de un ticket de tipo “Incidente”.
  3. Resolutor toma el ticket de tipo “Incidente”.
  4. Usuario se contacta con mesa de ayuda para generar un ticket de tipo “Reporte de Incidente” (teléfono, mail, autoatención).
  5. El sistema envía un correo automático al usuario con el número de ticket creado.
  6. Al resolver el ticket de tipo Incidente, se resuelven automáticamente todos los tickets de tipo “Incident Report” y se notifica automáticamente a los usuarios.

Problemas Principales:

  • Se mezclan incidentes de infraestructura (por ejemplo, servidor caído) con incidentes de negocio (por ejemplo, página web caída). La caída de un servidor podría no implicar la caída de un servicio de negocio, por lo que se dificulta la extracción de estadísticas para SLA diferenciando entre negocio e infraestructura.
  • La resolución de un incidente aún queda sujeta a validación, por lo que podría ser necesario ajustar la hora de resolución para tener estadísticas “reales”.

Posibles mejoras:

  • Separar los incidentes de infraestructura y de negocio en dos “colas” distintas (o agregar campo al ticket para diferenciarlos).
  • Configurar el monitoreo de manera que al limpiarse una alerta, se cierre el ticket asociado automáticamente. 

Escenario 4


  1. Monitoreo detecta falla en un componente de infraestructura. Se genera alerta que gatilla la generación automática de un ticket de tipo “Incidente de Infraestructura”.
  2. Monitoreo detecta falla en un servicio de negocio. Se genera alerta que gatilla la generación automática de un ticket de tipo “Incidente de Servicio”.
  3. Resolutor toma el ticket de tipo “Incidente de Infraestructura”.
  4. Usuario se contacta con mesa de ayuda para generar un ticket de tipo “Reporte de Incidente” (teléfono, mail, autoatención) por el problema con el servicio de negocio. Es asociado al ticket de Incidente de Servicio.
  5. El sistema envía un correo automático al usuario con el número de ticket creado.
  6. Resolutor resuelve el incidente. No le cambia estado al ticket en software de Service Desk.
  7. Monitoreos detectan recuperación de infraestructura y servicio de negocio.
  8. Monitoreos gatillan el cierre de los ticket de tipo “Incidente de Servicio/Infraestructura” asociados.
  9. Al resolver el ticket, se resuelven automáticamente todos los tickets de tipo “Reporte de Incidente” y se notifica automáticamente a los usuarios.
  10. Con la información de la investigación del incidente, se deben asociar los Incidentes de Servicio y de Infraestructura correspondientes (tarea manual).

Se pueden dar situaciones en que se gatille un incidente de infraestructura sin un incidente de servicio de negocio (por ejemplo, caída de un nodo de un cluster en alta disponibilidad que no afecte al servicio) o al revés (caída de un servicio producto de un bug en el software que no provoca caída de componentes de infraestructura).

Problemas principales:

  • Se pueden generar tickets duplicados si el sistema de tickets crea un ticket por cada correo de alarma que recibe y el monitoreo envía correos de alerta en períodos regulares para alarmas activas.
  • Los datos del incidente (categoría, urgencia, impacto, etc) quedan sujetos al criterio del agente que ingresa el ticket, por lo que deben ser constantemente validados para velar por la confiabilidad de los datos registrados.
  • No existe un método fácil de realizar seguimiento a los tickets para priorizarlos y actuar en caso de peligrar el cumplimiento del SLA.

Posibles mejoras:

  • Para el problema de tickets duplicados hay dos alternativas al menos:
    • Configurar monitoreo para que solo envíe un correo por cada alarma que se gatille.
    • Configurar el sistema de tickets para que si recibe tickets duplicados, los descarte y solo mantenga el original.
  • Configurar el sistema de tickets para que obtenga los campos del contenido del correo de alarma del sistema de monitoreo.
  • Se debe configurar el software de Service Desk para manejar SLA y prioridades y escalar automáticamente en caso de ser necesario. La prioridad se debe fijar automáticamente en base a la información del punto anterior.

Escenario 5


  1. Monitoreo detecta falla en un componente de infraestructura. Se genera alerta que gatilla la generación automática de un ticket de tipo “Incidente de Infraestructura”. Los detalles del incidente son llenados automáticamente y con ello se fija la prioridad del ticket y su SLA.
  2. Monitoreo detecta falla en un servicio de negocio. Se genera alerta que gatilla la generación automática de un ticket de tipo “Incidente de Servicio”. Los detalles del incidente son llenados automáticamente y con ello se fija la prioridad del ticket y su SLA.
  3. Resolutor toma el ticket de tipo “Incidente de Infraestructura”.
  4. Usuario se contacta con mesa de ayuda para generar un ticket de tipo “Reporte de Incidente” (teléfono, mail, autoatención) por el problema con el servicio de negocio. Es asociado al ticket de Incidente de Servicio.
  5. El sistema envía un correo automático al usuario con el número de ticket creado.
  6. Si se corre riesgo de no cumplir SLA para el servicio afectado, se gatillan los escalamientos correspondientes.
  7. Resolutor resuelve el incidente. No le cambia estado en software de Service Desk.
  8. Monitoreos detectan recuperación de infraestructura y servicio de negocio.
  9. Monitoreos gatillan el cierre de los ticket de tipo “Incidente de Servicio/Infraestructura” asociados.
  10. Al resolver el ticket, se resuelven automáticamente todos los tickets de tipo “Reporte de Incidente” y se notifica automáticamente a los usuarios.
  11. Con la información de la investigación del incidente, se deben asociar los Incidentes de Servicio y de Infraestructura correspondientes (tarea manual).

Posibles problemas:

  • Se puede dar la situación en que un usuario reporta un incidente que no fue detectado por el monitoreo, por lo que se debe registrar el “Incidente de Servicio” manualmente.
  • El monitoreo puede generar alertas preventivas en caso de que alguna métrica supere un umbral (uso de disco, por ejemplo), lo que generará incidentes por eventos que no implican interrupción del servicio.

Posibles mejoras:

  • Si un incidente no es detectado por el monitoreo, se debe implementar el monitor correspondiente.
  • Implementar una nueva cola para tickets de eventos, donde queden registradas las alarmas preventivas. Esta cola se puede usar para todo tipo de eventos (ver documentación ITIL).

Escenario 6...

Se pueden seguir implementando mejoras al proceso, pero en este punto ya contaríamos con un sistema que nos entrega información creíble de los incidentes y la gestión que se realiza de ellos. Algunos ejemplos de mejoras:

  • En paralelo a la generación del ticket se puede automatizar la actualización de una página de "estado de servicios". De esta manera, los usuarios pueden consultar esta página antes de ingresar un Reporte de Incidente. En la página de autoatención y en los correos que envía el service desk a los usuarios, se puede agregar un link a la página de estados de servicios.
  • El monitoreo, al generar el ticket, completa datos de CI afectado. Para ello, se debe enganchar el Service Desk con la CMDB (o implementar la CMDB en el mismo software de Service Desk).
  • Crear ticket de Problemas en base a los tickets de Incidentes. Como ya tenemos información de nuestros incidentes, además de el análisis manual de los incidentes, se pueden generar reglas que gatillen el inicio del proceso de gestión de problemas. Por ejemplo, si un CI tiene 3 incidentes en una semana, se genera automáticamente un problema.
  • Integrar este proceso con la gestión del cambio. El proceso de gestión del cambio podría contar con otra cola de tickets en el mismo software de Service Desk.
  • Integrar el proceso de gestión de incidentes con la base de datos de errores conocidos. La KEDB podría estar integrada en el mismo software de Service Desk.  

Post Mortem

Al cerrar un incidente se debe validar que esté bien documentado: que el valor de los campos sean correctos y que esté documentada la forma de resolución. Esto se debe realizar manualmente revisando todos los tickets creados de forma manual y auditando periódicamente los tickets creados de forma automática.
Es importante clasificar los incidentes para posterior categorización y extracción de estadísticas. Por ejemplo, se puede registrar:

  • El riesgo estaba identificado?
  • Causó interrupción del negocio?
  • Causó pérdida financiera?
  • Fue incidente de seguridad?
  • Fue un incidente de disponibilidad?
  • Fue un incidente de acceso no autorizado a información?
  • Hubo exposición pública?
  • Fue producto de un error de integración? (paso a producción?)
  • Fue por indisponibilidad de acceso a información?
  • Fue por no cumplimiento de políticas y/o procedimientos?
  • Fue por evasión de políticas y/o procedimientos? (excepción autorizada).
  • Severidad.



lunes, 23 de noviembre de 2015

Ceph Quick Tutorial

Instalación Ceph


  • Añadir repositorio

wget -q -O- 'https://download.ceph.com/keys/release.asc' | sudo apt-key add -
echo deb http://download.ceph.com/debian-hammer/ $(lsb_release -sc) main | sudo tee /etc/apt/sources.list.d/ceph.list

  • Instalar ceph

apt-get update && sudo apt-get install ceph

  • Configurar ntp

Cluster deploy


  • Para generar UUID para el cluster:

uuidgen

Deployar el primer monitor


  • Instalar Ceph
  • Crear archivo /etc/ceph/ceph.conf usando el UUID generado en paso anterior para fsid (asumiendo que el primer nodo que contendrá el monitor es node1 con ip 192.168.0.1):

fsid = {UUID}
mon initial members = node1
mon host = 192.168.0.1

  • Crear cluster keyring

ceph-authtool --create-keyring /tmp/ceph.mon.keyring --gen-key -n mon. --cap mon 'allow *'

  • Crear admin keyring

ceph-authtool --create-keyring /etc/ceph/ceph.client.admin.keyring --gen-key -n client.admin --set-uid=0 --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow'

  • Añadir el keyring admin al cluster

ceph-authtool /tmp/ceph.mon.keyring --import-keyring /etc/ceph/ceph.client.admin.keyring

  • Crear el monitor map

monmaptool --create --add {hostname} {ip-address} --fsid {uuid} /tmp/monmap
Ejemplo:
monmaptool --create --add node1 192.168.0.1 --fsid a7f64266-0894-4f1e-a635-d0aeaca0e993 /tmp/monmap

  • Crear el directorio para el monitor

mkdir /var/lib/ceph/mon/{cluster-name}-{hostname}
Por ejemplo:
mkdir /var/lib/ceph/mon/ceph-node1

  • Poblar el monitor

ceph-mon [--cluster {cluster-name}] --mkfs -i {hostname} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring
Por ejemplo:
ceph-mon --mkfs -i node1 --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring

  • Completar archivo de configuración (/etc/ceph/ceph.conf)

[global]
fsid = {cluster-id}
mon initial members = {hostname}[, {hostname}]
mon host = {ip-address}[, {ip-address}]
public network = {network}[, {network}]
cluster network = {network}[, {network}]
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
osd journal size = {n}
filestore xattr use omap = true
osd pool default size = {n}  # Write an object n times.
osd pool default min size = {n} # Allow writing n copy in a degraded state.
osd pool default pg num = {n}
osd pool default pgp num = {n}
osd crush chooseleaf type = {n}

Por ejemplo:
[global]
fsid = a7f64266-0894-4f1e-a635-d0aeaca0e993
mon initial members = node1
mon host = 192.168.0.1
public network = 192.168.0.0/24
auth cluster required = cephx
auth service required = cephx
auth client required = cephx
osd journal size = 1024
filestore xattr use omap = true
osd pool default size = 2
osd pool default min size = 1
osd pool default pg num = 333
osd pool default pgp num = 333
osd crush chooseleaf type = 1


  • Marcar configuración finalizada

touch /var/lib/ceph/mon/ceph-node1/done

  • Iniciar el monitor

start ceph-mon id=node1 [cluster={cluster-name}]
Por ejemplo:
start ceph-mon id=ceph01

  • Marcar para inicio automatico

touch /var/lib/ceph/mon/{cluster-name}-{hostname}/upstart
Por ejemplo:
touch /var/lib/ceph/mon/ceph-ceph01/upstart

Deployar monitores adicionales


  • Instalar Ceph
  • Copiar archivos de configuración y admin keyring desde el primer nodo a el/los nuevos monitores:

/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.conf

  • Crear el directorio para el monitor

mkdir /var/lib/ceph/mon/{cluster-name}-{hostname}
Por ejemplo:
mkdir /var/lib/ceph/mon/ceph-node2

  • Obtener keyring del monitor y monitor map

ceph auth get mon. -o /tmp/keyring
ceph mon getmap -o /tmp/monmap

  • Preparar el directorio del monitor

ceph-mon -i {mon-id} --mkfs --monmap /tmp/monmap --keyring /tmp/keyring
Por ejemplo:
ceph-mon -i ceph02 --mkfs --monmap /tmp/monmap --keyring /tmp/keyring

  • Iniciar el monitor

ceph-mon -i {mon-id} --public-addr {ip:port}
Por ejemplo:
ceph-mon -i ceph02 --public-addr 192.168.0.42:6789

  • Marcar para inicio automatico

touch /var/lib/ceph/mon/{cluster-name}-{hostname}/sysvinit
Por ejemplo:
touch /var/lib/ceph/mon/ceph-ceph02/sysvinit

Deployar OSD’s


  • Instalar Ceph
  • Copiar archivos de configuración, admin keyring y osd keyring desde el primer nodo a el/los nuevos osd:

/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.conf
/var/lib/ceph/bootstrap-osd/ceph.keyring

  • Preparar el dispositivo (por ejemplo: sdb)

ceph-disk prepare --cluster {cluster-name} --cluster-uuid {uuid} --fs-type {ext4|xfs|btrfs} {data-path} [{journal-path}]
Por ejemplo:
ceph-disk prepare --cluster ceph --cluster-uuid dac4c30b-3f86-46da-a12d-e4a33b49a60b --fs-type xfs /dev/sdb

  • Activar el OSD

ceph-disk activate {data-path} [--activate-key {path}]
Por ejemplo:
ceph-disk activate /dev/sdb1

CephFS


  • Instalar Ceph
  • Copiar archivos de configuración, admin keyring desde el primer nodo al nodo mds:

/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.conf


  • Crear el directorio para el nodo mds

mkdir -p /var/lib/ceph/mds/ceph-{nodo}
Por ejemplo:
mkdir -p /var/lib/ceph/mds/ceph-ceph01

  • Crear la llave para el MDS

ceph auth get-or-create mds.$MDS_NAME mds 'allow' osd 'allow *' mon 'allow profile mds' > /var/lib/ceph/mds/ceph-${MDS_NAME}/keyring
Por ejemplo:
ceph auth get-or-create mds.ceph01 mds 'allow' osd 'allow *' mon 'allow profile mds' > /var/lib/ceph/mds/ceph-ceph01/keyring

  • Crear los pools para data y metadata

ceph osd pool create ${CEPHFS_DATA_POOL} ${CEPHFS_DATA_POOL_PG}
ceph osd pool create ${CEPHFS_METADATA_POOL} ${CEPHFS_METADATA_POOL_PG}
Por ejemplo:
ceph osd pool create cephfs_data 8
ceph osd pool create cephfs_metadata 8

  • Crear el filesystem

ceph fs new ${CEPHFS_NAME} ${CEPHFS_METADATA_POOL} ${CEPHFS_DATA_POOL}
Por ejemplo:
ceph fs new cephfs cephfs_metadata cephfs_data

  • Iniciar demonio

ceph-mds -i ceph01

  • Marcar para inicio automatico

touch /var/lib/ceph/mds/{cluster-name}-{hostname}/sysvinit
Por ejemplo:
touch /var/lib/ceph/mds/ceph-ceph02/sysvinit

Configuración Cliente

Block storage


  • Instalar Ceph
  • Copiar archivos de configuración, admin keyring desde el primer nodo al nodo mds:

/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.conf

  • Crear el disco

rbd create {name} --size 4096 [-m {mon-IP}] [-k /path/to/ceph.client.admin.keyring]
Por ejemplo:
rbd create foo --size 4096

  • Mapear el disco a un dispositivo

rbd map {name} [-m {mon-IP}] [-k /path/to/ceph.client.admin.keyring]
Por ejemplo:
rbd map foo

  • Formatear y montar. Por ejemplo

mkfs.ext4 -m0 /dev/rbd/rbd/foo
mkdir /mnt/ceph-block-device
mount /dev/rbd/rbd/foo /mnt/ceph-block-device

CephFS


  • Instalar Ceph
  • Copiar archivos de configuración, admin keyring desde el primer nodo al nodo mds:

/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.conf

  • Crear archivo con key

# cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
        key = AQDVuzxWf/qiAhAAt9jKW6N6zGtgVVY0tzcK3A==
        auid = 0
        caps mds = "allow"
        caps mon = "allow *"
        caps osd = "allow *"
# echo AQDVuzxWf/qiAhAAt9jKW6N6zGtgVVY0tzcK3A== > /etc/ceph/admin.secret

  • Montar el filesystem

mount -t ceph 192.168.0.1:6789:/ /mnt/mycephfs -o name=admin,secretfile=admin.secret

Ceph y Openstack

Usar Ceph como backend para Volumes en Openstack


  • Instalar Ceph en nodos compute (nova) y block storage (cinder)
  • Copiar archivos de configuración desde el primer nodo a los nodos nova y cinder:

/etc/ceph/ceph.conf

  • Crear pool

ceph osd pool create volumes 64

  • Crear usuario en ceph

ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes'

  • Añadir el keyring generado en los nodos nova y cinder
    • En un nodo admin

ceph auth get-or-create client.cinder | tee /etc/ceph/ceph.client.cinder.keyring

    • Luego copiar el keyring a los nodos nova y cinder
  • Configurar libvirt en nodos nova
    • Generar un uuid

uuidgen

    • Tomar nota del key del usuario cinder

ceph auth get-key client.cinder

    • Crear archivo xml

cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>457eb676-33da-42ec-9a8c-9293d545c337</uuid>
  <usage type='ceph'>
    <name>client.cinder secret</name>
  </usage>
</secret>
EOF

    • Ejecutar

virsh secret-define --file secret.xml

    • Ejecutar

virsh secret-set-value --secret 457eb676-33da-42ec-9a8c-9293d545c337 --base64 AQCek0BW9DzSMxAAdN7i5ieDw0pVJepIZTLFiQ==

  • En nodo cinder, editar archivo /etc/cinder/cinder.conf. En parámetro “enabled_backends” usar rbd y añadir sección:

[rbd]
volume_driver = cinder.volume.drivers.rbd.RBDDriver
rbd_pool = volumes
rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_flatten_volume_from_snapshot = false
rbd_max_clone_depth = 5
rbd_store_chunk_size = 4
rados_connect_timeout = -1
glance_api_version = 2
rbd_user = cinder
rbd_secret_uuid = 457eb676-33da-42ec-9a8c-9293d545c337

  • En nodos nova, en archivo /etc/nova/nova-compute.conf, en sección [libvirt], añadir:

rbd_user = cinder
rbd_secret_uuid = 457eb676-33da-42ec-9a8c-9293d545c337

  • Reiniciar servicio en cinder

service cinder-volume restart

  • Reiniciar servicio en nova

service nova-compute restart

Usar Ceph como backend para VM’s en Openstack

TODO

martes, 17 de noviembre de 2015

Inventario de Herramientas

Un par de links útiles



Analytics

Application Server

Automatización

Backups

Balanceo de Carga

Blog

Business Intelligence

Cloud

Cluster

CMDB (Asset Management)

Code Search

Colaboración

Wiki

Colas de mensajería

Computación distribuida

Continuous Integration

Control de Cambios

Control de Incidencias - ALM (Application Lifecycle Management) - Gestión de Proyectos

Control de versiones

CRM

Domain Controller

Email Marketing

ERP

Gestión de documentos - BPM

Governance

Help Desk

Identity Management

Library Hub

Ruby

Middleware

Monitoreo

APM

End User Experience

JVM

Networking

Orquestación

Password Management

Java

Repositorio de logs

Repository Management

Revisión de Código

Seguridad

Service Discovery

Servicio de Directorio

Status Page System

Storage

Testing

Time Tracking

Virtualización

Virtual Appliances

VTL