Configurar NTP en Red Hat 7

Estoy empezando a montar servidores con Red Hat 7 y hay muchas cosas nuevas. Una de ellas ha sido el servicio de NTP, que deja e ser controlado por el demonio ntpd. Ahora el servicio es Chrony. Si no lo sabes es posible que estés un rato intentando configurando el ntpd y tras reiniciar el servidor lo encuentres parado.

[root@jupiter ~]# systemctl status ntp

ntpd.service - Network Time Service

Loaded: loaded (/usr/lib/systemd/system/ntpd.service; enabled)

Active: inactive (dead)

Viendo como esta definido el servicio chronyd vemos que es incompatible con el servicio ntpd. Por tanto deberemos elegir entre uno u otro:

[root@jupiter ~]# more /usr/lib/systemd/system/chronyd.service [Unit] Description=NTP client/server After=ntpdate.service sntp.service ntpd.service Conflicts=ntpd.service

[Service]
Type=forking
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd -u chrony $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper add-dhclient-servers

[Install]
WantedBy=multi-user.target

Tras reiniciar el servidor este servicio arranca al estar habilitado y no tener incompatibilidades con otros servicios :

[root@jupiter ~]# systemctl status chronyd
chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled)
Active: active (running) since jue 2015-04-23 14:29:00 CEST; 1min 52s ago
Process: 2257 ExecStartPost=/usr/libexec/chrony-helper add-dhclient-servers (code=exited, status=0/SUCCESS)
Process: 2250 ExecStart=/usr/sbin/chronyd -u chrony $OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 2254 (chronyd)
CGroup: /system.slice/chronyd.service
└─2254 /usr/sbin/chronyd -u chrony

El fichero de configuración es el siguiente:

[root@jupiter ~]# more /etc/chrony.conf
# These servers were defined in the installation:
server 0.rhel.pool.ntp.org iburst
server 1.rhel.pool.ntp.org iburst
server 2.rhel.pool.ntp.org iburst
server 3.rhel.pool.ntp.org iburst

stratumweight 0

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift

# Enable kernel RTC synchronization.
rtcsync

# In first three updates step the system clock instead of slew
# if the adjustment is larger than 10 seconds.
makestep 10 3

# Listen for commands only on localhost.
bindcmdaddress 127.0.0.1
bindcmdaddress ::1

keyfile /etc/chrony.keys

# Specify the key used as password for chronyc.
commandkey 1

# Generate command key if missing.
generatecommandkey

# Disable logging of client accesses.
noclientlog

# Send a message to syslog if a clock adjustment is larger than 0.5 seconds.
logchange 0.5


logdir /var/log/chrony

En la documentación de Red Hat nos recomiendan en que casos usar un demonio u otro:
– En sistemas que se reinicien a menudo o que entren en hibernación recomiendan utilizar Chronyd.
– En sistemas que estén permanentemente encendidos recomiendan utilizar Ntpd.
Según cada caso instalaremos uno u otro, pero no los dos.

Para más información:

1. Documentación oficial de Red Hat
2. http://www.certdepot.net/rhel7-set-ntp-service/

Compilar PHP de 32 bits en Red Hat de 64 bits

Por una incopatibilidad entre aplicaciones he tenido que compilar la última versión de PHP en un servidor de 64 bits. El proceso es bastante sencillo si se tienen correctamente instaladas las librerias de 32 bit en el sistema. 

En este sistema ya tenia una serie de librerias de 32 bits instaladas, pero ha sido necesario instalar algunas mas para poder compilar correctamente. En concreto, las que hacian falta eran:

libstdc++-devel.i686
glib2.i686
zlib-devel.i686

Para instalarlas se puede hacer con yum.
Descargar el codigo fuente de la última versión de php desde la web de php.net en el servidor. Una vez verificado el MD5 procederíamos a descomprimir el código fuente en /var/tmp:

# md5sum php-5.6.4.tar.bz2
d31629e9c2fb5f438ab2dc0aa597cd82 php-5.6.4.tar.bz2
# tar xjvf php-5.6.4.tar.bz2

Una vez en la carpeta del codigo fuente exportaremos las variables CFLAGS, CXXFLAGS y LDFLAGS donde indicaremos que la arquitectura sobre la que se debe compilar es de 32 bits:

# export CFLAGS=’-m32′
# export CXXFLAGS=’-m32′
# export LDFLAGS=’-m32′

Si ya habíamos intentado compilar deberemos ejecutar un “make clean” y a continuación configurar la compilación:

# ./configure –libdir=/lib  –prefix=/usr/local/php-5.6.4 –with-libdir=/lib

Este proceso finaliza con la recomendación de ejecutar un test antes del install, con lo que ejecutaremos lo siguiente:

# make test && make install

Al finalizar la compilación la nueva versión de PHP quedará instalada en /usr/local/php-5.6.4 y veremos que es un binario de arquitectura de 32 bits:

# pwd
/usr/local/php-5.6.4/bin
# ./php -v
PHP 5.6.4 (cli) (built: Dec 23 2014 11:43:42)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
# file php
php: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped

El servidor web se deberá configurar para que apunte a este binario.
Una vez sabemos que compila se debería recompilar con las opciones de configuración que sean necesarias en cada caso (módulos y extensiones).

#TIP

Como he comentado anteriormente, este sistema ya tenia una serie de librerias de 32 bits instaladas:

zlib.i686
libstdc++-devel.i686
libxcb.i686
libaio.i686
libXtst.i686
libstdc++.i686
libzip.i686
libXau.i686
libXi.i686
libxml2-devel.i686
glibc-devel.i686
gamin.i686
nss-softokn-freebl.i686
libXext.i686
compat-libstdc++-33.i686
glibc.i686
libselinux.i686
glib2.i686
zlib-devel.i686
libuuid.i686
libxml2.i686
libgcc.i686
libX11.i686
libaio-devel.i686
libXrender.i686
libzip-devel.i686
compat-libcap1.i686
libXp.i686

Para instalarlas todas con un comando lo que se puede hacer es copiar el listado en un fichero e instalarlo con yum de la siguiente manera:

# vi /tmp/paquetes
# yum install $(cat /tmp/paquetes)

Fallo al arrancar máquinas virtuales despues de migrar oVirt a 3.5

Recientemente he actualizado una instalación de oVirt de la versión 3.4 a la versión 3.5. El proceso es bastante trasparente y básicamente consiste en actualizar el repositorio y seguir los mismos pasos que durante la instalación. Una vez con la nueva versión podemos actualizar la compatibilidad del cluster que tengamos configurado a la versión 3.5. Para ello es recomendable poner los hosts en mantenimiento. Una vez actualizado se pueden actualizar también los Hosts. Ya con todo actualizado vemos que hay funcionalidades nuevas, como la gestión de memoria con NUMA. 
Esta funcionalidad puede ser interesante en entornos que requieren un uso intensivo de CPU y Memoria, pero debe estar bien configurado. Si, como en mi caso, tenemos un entorno mas estándar no es necesario configurarlo, pero al intentar arrancar las máquinas de nuevo podemos tener el siguiente error:
VM compute1 is down with error. Exit message: internal error internal error NUMA memory tuning in ‘preferred’ mode only supports single node.
Para solucionarlo basta seguir los pasos que se indican en la lista de distribución:
Resumiendo, hay que editar la máquina virtual que presenta los problemas y acceder a la opción Host:
Allí veremos que el “Tune Mode” esta deshabilitado y configurado por defecto en “Preferred”. Para poder cambiarlo seleccionaremos un host sobre el que correrá esta máquina y deshabilitaremos las migraciones. En ese momento ya podemos seleccionar la opción “Interleave” como “Tune Mode”:
Una vez cambiado podemos volver los parámetros por defecto. Una vez aplicados podremos arrancar la máquina

Agilizando la Infraestructura IV: Trabajando con oVirt

En el post anterior vimos como instalar y configurar oVirt dejándolo preparado para el despliegue de máquinas virtuales. En este post explicaré como configurar el repositorio de imágenes ISO, de forma que podamos arrancar una máquina virtual y asignarle una imagen de instalación por ejemplo. A continuación veremos como integrarlo con Foreman de forma que el despliegue de las máquinas virtuales lo hagamos desde Foreman como si fuese una máquina física.

Repositorio de imágenes

Durante la instalación se ha creado un Storage Domain que debemos configurar y que aparece como “Unattached”. Al seleccionarlo, en la consola inferior seleccionamos la pestaña “Data Center” y a continuación lo activamos con el boton de “Attach”:

A continuación nos aparecerá una ventana donde indicaremos al “Data Center” donde lo queremos añadir, en nuestro caso, al solo tener uno no tendremos mas opción:

En este punto ya podremos subir imágenes. No he encontrado otra forma de subirlas, y al parecer hay que hacerlo desde la línea de comandos con la herramienta engine-iso-uploader:


[root@ovirt ~]# engine-iso-uploader upload -i ISO_DOMAIN /var/lib/exports/iso/ubuntu-14.04-desktop-amd64.iso
Please provide the REST API password for the admin@internal oVirt Engine user (CTRL+D to abort):
Uploading, please wait…
INFO: Start uploading /var/lib/exports/iso/ubuntu-14.04-desktop-amd64.iso  

A los pocos minutos la imagen estará subida y disponible para añadirla a alguna máquina virtual. Así mismo, podemos ver el listado de imágenes que tenemos subidas desde la interfaz web:

Integración con Foreman

La integración con Foreman es bidireccional. Por una parte una vez integrado, desde Foreman, seremos capaces de provisionar máquinas virtuales y aplicarle las clases que hayamos definido como si de una máquina física se tratara. Por otro lado, desde oVirt, podremos acceder al inventario de máquinas de Foreman para el caso de que quisieramos añadir mas hosts, por ejempo.
Para el primer caso, desde la consola de Foreman accederemos al menú “Infraestructure/Compute Resources” y configuraremos la URL de la API de oVirt. También deberemos especificar el usuario administrador y su password. Finalmente probaremos la conexión para poder obtener el certificado e importarlo:
Para la integración en el otro sentido, desde la consola de oVirt añadiremos en este caso la URL de la API de Foreman desde la rama “External Providers” y con el botón de “Add”:

Creación de máquinas virtuales

Para la creación de máquinas virtuales podríamos seguir el método clásico de crear una nueva máquina e instalarle el sistema operativo desde el CD que le hayamos asignado. Sin embargo, aprovechando que tenemos nuestra instalación de Foreman, realizaremos el aprovisionamiento de las máquinas virtuales con el.
En la interfaz de Foreman, iremos a añadir un nuevo Host, y tras ponerle el nombre y asignarle el Host Group le pondremos que el despliegue se realice sobre oVirt. Esta opción se ha habilitado gracias a la integración que hemos configurado anteriormente. Veremos además que aparece una nueva pestaña de “Virtual Machine” donde podremos configurar parámetros específicos:

En la pestaña “Virtual Machine” le asignaremos los recursos que queremos que tenga nuestra máquina virtual: número de cores y memoria. También deberemos añadirle una interfaz de red y uno o mas discos, marcando que uno de ellos sea bootable:

En este punto ya veremos en la interfaz de oVirt que se ha creado una nueva máquina con el nombre que le hemos especificado y empezará la instalación de la misma.
Para poder ver la consola, desde Ubuntu deberemos instalar el paquete virt-viewer. Al acceder a la consola con Firefox nos pedirá con que programa abrirlo, a lo que deberemos seleccionar “Remote viewer”

julian@ubuntu:~$ sudo apt-get install virt-viewer  

Agilizando la Infraestructura III: oVirt 3.4 con glusterFS

En esta entrada voy a explicar como he instalado un entorno de virtualización basado en oVirt 3.4 y utilizando como almacenamiento compartido volúmenes de glusterFS. oVirt requiere de un nodo de control y varios nodos de computación. La arquitectura viene a ser bastante similar a la que podríamos tener con VMware vSphere. He instalado el motor de gestión en un servidor físico con 2 CPU y 1 GB de RAM. Si bien los requisitos son mucho mayores, para la demo que he preparado va bastante bien aunque le puede llegar a faltar algo de fluidez.

Instalación de oVirt

La instalación, como en todos los productos en los que Red Hat está por detras, se realiza desde un RPM. Se instala primero un rpm que nos configurará los repositorios oficiales de ovirt y a continuación se instala el paquete ovirt-engine:

[root@ovirt ~]# yum install http://plain.resources.ovirt.org/pub/yum-repo/ovirt-release34.rpm
[root@ovirt ~]# yum -y install ovirt-engine

 Una vez instalado se lanza la configuración donde deberemos responder algunas preguntas:

[root@ovirt ~]# engine-setup
[ INFO ] Stage: Initializing
[ INFO ] Stage: Environment setup
Configuration files: [‘/etc/ovirt-engine-setup.conf.d/10-packaging.conf’]
Log file: /var/log/ovirt-engine/setup/ovirt-engine-setup-20140704130518-cgito9.log
Version: otopi-1.2.1 (otopi-1.2.1-1.el6)
[ INFO ] Stage: Environment packages setup
[ INFO ] Yum Downloading: repomdSYOvZitmp.xml (0%)
[ INFO ] Stage: Programs detection
[ INFO ] Stage: Environment setup
[ INFO ] Stage: Environment customization

–== PRODUCT OPTIONS ==–


–== PACKAGES ==–

[ INFO ] Checking for product updates…
[ INFO ] No product updates found

–== NETWORK CONFIGURATION ==–

Host fully qualified DNS name of this server [ovirt.enterprise.com]:
Setup can automatically configure the firewall on this system.
Note: automatic configuration of the firewall may overwrite current settings.
Do you want Setup to configure the firewall? (Yes, No) [Yes]: yes
The following firewall managers were detected on this system: iptables Firewall manager to configure (iptables): iptables
[ INFO ] iptables will be configured as firewall manager.

–== DATABASE CONFIGURATION ==–

Where is the Engine database located? (Local, Remote) [Local]:
Setup can configure the local postgresql server automatically for the engine to run. This may conflict with existing applications.
Would you like Setup to automatically configure postgresql and create Engine database, or prefer to perform that manually? (Automatic, Manual) [Automatic]:

–== OVIRT ENGINE CONFIGURATION ==–

Application mode (Both, Virt, Gluster) [Both]:
Default storage type: (NFS, FC, ISCSI, POSIXFS, GLUSTERFS) [NFS]: GLUSTERFS
Engine admin password:
Confirm engine admin password:
–== PKI CONFIGURATION ==–

Organization name for certificate [enterprise.com]:

–== APACHE CONFIGURATION ==–

Setup can configure apache to use SSL using a certificate issued from the internal CA.
Do you wish Setup to configure that, or prefer to perform that manually? (Automatic, Manual) [Automatic]:
Setup can configure the default page of the web server to present the application home page. This may conflict with existing applications.
Do you wish to set the application as the default page of the web server? (Yes, No) [Yes]:

–== SYSTEM CONFIGURATION ==–

Configure WebSocket Proxy on this machine? (Yes, No) [Yes]:
Configure an NFS share on this server to be used as an ISO Domain? (Yes, No) [Yes]:
Local ISO domain path [/var/lib/exports/iso]:
Local ISO domain ACL [0.0.0.0/0.0.0.0(rw)]:
Local ISO domain name [ISO_DOMAIN]:

–== MISC CONFIGURATION ==–


–== END OF CONFIGURATION ==–

[ INFO ] Stage: Setup validation
–== CONFIGURATION PREVIEW ==–

Engine database name : engine
Engine database secured connection : False
Engine database host : localhost
Engine database user name : engine
Engine database host name validation : False
Engine database port : 5432
NFS setup : True
PKI organization : enterprise.com
Application mode : both
Firewall manager : iptables
Update Firewall : True
Configure WebSocket Proxy : True
Host FQDN : ovirt.enterprise.com
NFS export ACL : 0.0.0.0/0.0.0.0(rw)
NFS mount point : /var/lib/exports/iso
Datacenter storage type : glusterfs
Configure local Engine database : True
Set application as default page : True
Configure Apache SSL : True

Please confirm installation settings (OK, Cancel) [OK]:
[ INFO ] Stage: Transaction setup
[ INFO ] Stopping engine service
[ INFO ] Stopping websocket-proxy service
[ INFO ] Stage: Misc configuration
[ INFO ] Stage: Package installation
[ INFO ] Stage: Misc configuration
[ INFO ] Initializing PostgreSQL
[ INFO ] Creating PostgreSQL ‘engine’ database
[ INFO ] Configuring PostgreSQL
[ INFO ] Creating Engine database schema
[ INFO ] Creating CA
[ INFO ] Configuring WebSocket Proxy
[ INFO ] Generating post install configuration file ‘/etc/ovirt-engine-setup.conf.d/20-setup-ovirt-post.conf’
[ INFO ] Stage: Transaction commit
[ INFO ] Stage: Closing up

–== SUMMARY ==–SSH fingerprint: 83:1F:BB:B9:DC:7B:94:D3:41:38:67:AC:33:E9:58:AE Internal CA 7E:BE:5C:B7:34:DD:E3:EB:2D:44:18:1B:E4:B8:3B:BE:33:BB:99:14 Web access is enabled at:
http://ovirt.enterprise.com:80/ovirt-engine https://ovirt.enterprise.com:443/ovirt-engine
Please use the user “admin” and password specified in order to login

–== END OF SUMMARY ==–

[ INFO ] Starting engine service
[ INFO ] Restarting httpd
[ INFO ] Restarting nfs services
[ INFO ] Stage: Clean up
Log file is located at /var/log/ovirt-engine/setup/ovirt-engine-setup-20140704130518-cgito9.log
[ INFO ] Generating answer file ‘/var/lib/ovirt-engine/setup/answers/20140704131454-setup.conf’
[ INFO ] Stage: Pre-termination
[ INFO ] Stage: Termination


[ INFO ] Execution of setup completed successfully

Con las pocas preguntas que hemos respondido ya nos instala todo lo necesario y nos habilita el acceso a la consola web. También nos ha configurado un repositorio de imágenes ISO que mas adelante mostraré como usar y terminar de configurar.

Interfaz web

Si accedemos a la URL que nos ha devuelto el proceso de configuración veremos que nos ha habilitado varios portales, entre ellos el de administración:

Accedemos al portal y lo primero que haremos será añadir dos hosts al cluster. Para crear los hosts existen dos opciones:

  • utilizar una imagen desde la web de oVirt con la que se instala el sistema operativo y todo lo necesario
  • utilizar un sistema operativo ya preinstalado al que se le instalará el software necesario al agregarlo al cluster.

En mi caso ya disponia de dos servidores instalados con lo que los he añadido al cluster. Previamente he configurado los repositorios de oVirt al igual que hice para instalar el motor. A continuación desde la interfaz web añadomos el host e introduciremos los datos del usuario root para que pueda instalar el software:

En la parte inferior podemos ver los eventos y tareas que se están ejecutando. En el se puede ver que se está ejecutando YUM en los servidores para instalar el software de oVirt.

Almacenamiento

Una vez instalado los nodos sobre los que correrán las máquinas virtuales es necesario la configuración de un almacenamiento compartido. He elegido GlusterFS por las bondades de HA y performance que tiene. GlusterFS lo configuro sobre dos servidores adicionales, aunque bien podría instalarse en los mismos servidores donde van a correr las máquinas virtuales.

La instalacioń es secilla:

[root@storage01 ~]# yum install -y glusterfs glusterfs-fuse glusterfs-server

Una vez instalado se configuran los pares y ya se puede crear un volumen e iniciarlo:

[root@storage01 ~]# gluster peer probe storage02
peer probe: success.[root@storage01 ~]# gluster peer status
Number of Peers: 1

Hostname: storage02
Uuid: 3e4056d0-2ab0-4e83-b273-ceb565b7458c
State: Peer in Cluster (Connected)
[root@storage01 #]# gluster volume create DATA replica 2 transport tcp storage01:/opt/gluster/data storage02:/opt/gluster/data
volume create: DATA: success: please start the volume to access data
[root@storage01 ~]# gluster volume start DATA


volume start: DATA: success  

He creado un volúmen con dos réplicas, de forma que si perdemos una de las dos no habría pérdida de datos. Para poder utilizarlo en oVirt se deben realizar algunas modificaciones:

[root@storage01 ~]# gluster volume set DATA allow-insecure on[root@storage01 ~]# gluster volume set DATA server.allow-insecure on
[root@storage01 ~]# gluster volume set DATA storage.owner-uid=36
[root@storage01 ~]# chown 36:36 /opt/gluster/data
[root@storage01 ~]# gluster volume info

Volume Name: DATA
Type: Replicate
Volume ID: 6361b068-7601-4903-88c4-5cdc50f28236
Status: Started
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: storage01:/opt/gluster/data
Brick2: storage02:/opt/gluster/data
Options Reconfigured:
server.allow-insecure: on


storage.owner-uid: 36

También se debe modificar el fichero /etc/glusterfs/glusterd.vol añadiendo la opción rcp-auth-allow-insecure:

[root@storage01 ~]# vi /etc/glusterfs/glusterd.volvolume management
type mgmt/glusterd
option working-directory /var/lib/glusterd
option transport-type socket,rdma
option transport.socket.keepalive-time 10
option transport.socket.keepalive-interval 2
option transport.socket.read-fail-log off
# option base-port 49152
option rpc-auth-allow-insecure on


end-volume

Una vez realizado estos cambios se debe reiniciar el demonio en los nodos:

[root@storage01 ~]# service glusterd restart
Starting glusterd: [ OK ]

Por último, en los Hosts de oVirt es necesario instalar el paquete vdsm-gluster para que puedan montar los volúmenes:

[root@compute01 ~]# sudo yum install vdsm-gluster

Con todo ya configurado se puede crear el dominio de almacenamiento y mapear el volúmen que hemos creado anteriormente:

Ya está todo preparado para poder empezar a crear máquinas virtuales. En la siguiente entrada explicaré como crear el repositorio de imágenes y como integrar oVirt con Foreman.

Agilizando la Infraestructura II: Despliegue de sistemas con Foreman

Ya vimos en la entrada anterior cómo instalar y configurar Foreman para poder realizar despliegues de una manera desatendida. Veamos a continuación como se despliega un sistema.

En la pantalla principal de Foreman accederemos al menú Hosts y seleccionaremos New host.  


Nos aparecerá un wizard muy sencillo donde especificaremos algunos datos, como la MAC de la interfaz de red configurada para arrancar el servidor. También le indicaremos el “host group” y el entorno que le queremos asignar.  Esto nos permitirá aplicar al servidor unas clases de Puppet u otras.
Como se puede ver, también se puede indicar qué tipo de despliegue se quiere hacer, en este caso Bare Metal, para instalar un servidor físico, pero podríamos integrar Foreman con Openstack o con oVirt por ejemplo, y nos serviría para desplegar instancias virtuales.

 En la pestaña de Network especificaremos la MAC de la interfaz de red así como la dirección IP que queremos asignarle al servidor. En cualquier caso nos sugerirá una IP del rango DHCP que hayamos configurado, pero siempre podremos cambiarla:

En la pestaña Operating System indicamos el sistema operativo a instalar, el repositorio que debe utilizar, la tabla de partición que le queramos aplicar y finalmente la password del usuario root.

 Podemos darle ya al botón Submit para que quede configurado el servidor. En el próximo reinicio el servidor arrancará por red (si no arranca verificar la configuración de la BIOS) e iniciará la instalación del sistema operativo:

 

 A medida que vayamos instalando servidores se irán añadiendo a la lista de servidores y se le irán aplicando las clases que hayamos configurado al Host Group asignado:

En próximas entradas veremos cómo integrarlo con oVirt.

Agilizando la infraestructura I: Provisioning

Estoy evaluando soluciones para poder modernizar la infraestructura que manejamos actualmente. La tendencia es ir a un modelo IaaS, pero tampoco se puede pasar de un modelo tradicional (de principio de siglo) a un IaaS completo en unos meses.

Lo primero que planteo es el tema del aprovisionamiento de servidores, ya sean físicos o virtuales. Hasta ahora veníamos utilizando herramientas de Oracle, puesto que la mayoría de los servidores que administrábamos eran Solaris. Pero últimamente empezamos a tener cada vez mas servidores linux y el uso de estas herramientas de Oracle es muy tedioso.

Entre las herramientas que he encontrado, la que mas me ha gustado y con la que he empezado a hacer pruebas es Foreman. Foreman se trata de una herramienta Open Source que utiliza puppet para gestionar el ciclo de vida de los servidores y ademas esta soportada por Red Hat, con lo que se garantiza que el proyecto tiene la suficiente calidad como para integrarlo en un entorno empresarial.

Instalación de Foreman
La instalación, como siempre que se utilizan repositorios, no puede ser mas sencilla. Se añaden los repositorios del proyecto (y el EPEL en caso de no tenerlo ya) y en este caso se instala el programa que se encargará de la configuración:

[root@foreman ~]# yum -y install http://yum.theforeman.org/releases/1.5/el6/x86_64/foreman-release.rpm
[root@foreman ~]# yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@foreman ~]# yum -y install foreman-installer

Como nota, en la web de Foreman recomiendan instalarlo en un servidor que disponga de la versión Open Source de puppet, puesto que al parecer es incompatible con la versión Enterprise.

El instalador se puede lanzar de varias formas, a mi me gusta el modo interactivo. Una de las cosas que hay que tocar el el tipo de Base de Datos. Por defecto es Postgres, pero si mas adelante se quiere integrar Foreman con Packstack será necesario pasar a una base de datos MySQL, con lo que yo lo cambio antes de empezar.

    [root@foreman ~]# foreman-installer -i
    Welcome to the Foreman installer!
    ———————————

    This wizard will gather all required information. You can change any parameter
    to your needs.

    Ready to start? (y/n)
    y
    Main Config Menu
    1. [✓] Configure foreman_plugin_templates
    2. [✓] Configure foreman_proxy
    3. [✓] Configure foreman_plugin_puppetdb
    4. [✓] Configure foreman_compute_openstack
    5. [✓] Configure foreman_plugin_discovery
    6. [✓] Configure foreman_plugin_default_hostgroup
    7. [✗] Configure foreman_plugin_chef
    8. [✓] Configure foreman_plugin_bootdisk
    9. [✗] Configure foreman_compute_rackspace
    10. [✗] Configure foreman_plugin_hooks
    11. [✓] Configure foreman #para cambiar el tipo de BBDD
    12. [✗] Configure foreman_compute_vmware
    13. [✓] Configure foreman_compute_ovirt
    14. [✓] Configure foreman_plugin_setup
    15. [✗] Configure foreman_compute_gce
    16. [✗] Configure foreman_compute_ec2
    17. [✓] Configure puppet
    18. [✓] Configure foreman_compute_libvirt
    19. Display current config
    20. Save and run
    21. Cancel run without Saving
    Choose an option from the menu… 20

El instalador empieza a ejecutar varios módulos de puppet e instala y configura todo lo necesario. En unos minutos tenemos nuestro servidor de foreman preparado:

    Installing — /etc/httpd/conf/httpd.confhed2014-03-20 11:17:58 [38%] [……………………….. Installing — /etc/sysconfig/foremanig/fore2014-06-18 11:00:08.000 [99%] [………………………………………………………………Installing Done [100%] […………………………………………………………………]
    Success!
    * Foreman is running at https://foreman.globalia.com
    Default credentials are ‘admin:changeme’
    * Foreman Proxy is running at https://foreman.globalia.com:8443
    * Puppetmaster is running at port 8140
    The full log is at /var/log/foreman-installer/foreman-installer.log

Configuración del provisioning

Para configurar el provisoning existe un wizard donde se especifican el origen del software y la configuración básica de red. Se accede a través del menú Infrastructure/Provisioning setup:

En el primer paso indicamos sobre que segmento de red se va a hacer el autoprovisioning:

A continuación varios datos sobre la red:

​En el paso 3 nos indicará que ejecutemos de nuevo el instalador de Foreman adaptado a nuestra configuración. Nos dará dos opciones, si queremos utilizar DHCP o no:

​En el cuarto paso se selecciona el origen de los medios de instalación. Se pueden utilizar los repositorios públicos, pero es recomendable utilizar un repositorio local para acelerar el proceso de instalación:

​En el último paso ya podemos lanzar la creación de nuevos servidores, pero antes es necesario configurar algunas cosas mas.

Creación del repositorio:
Lo mas sencillo para crear un repositorio local es utilizar los DVD de instalación, en este caso de CentOS 6.5. Se copian los rpm a la carpeta que contendrá nuestro repositorio:

[root@foreman ~]# cd /opt/jgp/
[root@foreman jgp]# mkdir -p repo/centos/6.5/x86_64/repodata
[root@foreman jgp]# cp -a /media/DVD/dvd1/Packages/*.rpm repo/centos/6.5/x86_64/
[root@foreman jgp]# cp -a /media/DVD/dvd2/Packages/*.rpm repo/centos/6.5/x86_64/

Se copian las imágenes de inicio y el xml también al repositorio:

[root@foreman jgp]# cd repo/centos/6.5/x86_64/
[root@foreman x86_64]# cp -r /media/DVD/dvd1/images .
[root@foreman x86_64]# cp /media/DVD/dvd1/repodata/*comps*.xml repodata/comps.xml

A continuación se instala el paquete createrepo y se genera de nuevo el xml:

[root@foreman centos6.5]# yum install createrepo
[root@foreman centos6.5]# createrepo -g repodata/comps.xml .
Spawning worker 0 with 6367 pkgs
Workers Finished
Gathering worker results

Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete

Lo ultimo que debemos hacer es habilitar el acceso, en este caso habilito el acceso anónimo por ftp. Instalaré el servidor vsftpd y configuraré el directorio donde he ubicado el repositorio como público:

[root@foreman centos6.5]# yum install vsftpd
[root@foreman pub]# service vsftpd start
Starting vsftpd for vsftpd: [ OK ]
[root@foreman ~]# vi /etc/vsftpd/vsftpd.conf
anon_root=/opt/jgp/repo #public directory
[root@foreman bin]# service vsftpd start
Starting vsftpd for vsftpd: [ OK ]
[root@foreman bin]# chkconfig vsftpd on

Plantilla del Sistema Operativo

Se deberá crear una plantilla para el despliegue de los sistemas. Será necesario especificar una tabla de partición. En principio se puede  utilizar la que viene por defecto, pero también podemos crear una y adaptarla a nuestras necesidades. Yo voy a instalar los servidores físicos que disponen de mas de un disco de la siguiente forma:

  1. Mirror de la partición 1 de cada disco de un tamaño de 25 gigas para /.
  2. Mirror de la partición 2 de cada disco de un tamaño de 2 gigas para swap.
  3. Stripe con LVM de lo que queda de disco y se utilizará para datos.

En Foreman accederemos a partition tables y crearemos la nuestra según estos criterios:

El contenido del layout será el siguiente:

zerombr

clearpart –all –initlabel –drives=sda,sdb

part raid.008001 –asprimary –ondrive=sda –size=25000
part raid.008002 –asprimary –ondrive=sda –size=2048
part pv.008003 –asprimary –ondrive=sda –grow –size=25000

part raid.008011 –asprimary –ondrive=sdb –size=25000
part raid.008012 –asprimary –ondrive=sdb –size=2048
part pv.008013 –asprimary –ondrive=sdb –grow –size=25000

raid / –fstype=ext4 –level=1 –device=md0 raid.008001 raid.008011
raid swap –level=1 –device=md1 raid.008002 raid.008012
volgroup vg_data –pesize=4096 pv.008003 pv.008013
logvol /opt/jgp –fstype=xfs –name=jgp –vgname=vg_data –grow –size=100

Una vez configurado el particionado que utilizarán nuestros sistemas pasamos a configurar el origen del software para nuestra instalación, que apuntará al repositorio que hemos creado anteriormente. En installation media crearemos una plantilla nueva:

​Ya por último crearemos la plantilla del sistema operativo que queremos desplegar. Para ello iremos a operating systems y allí crearemos uno nuevo, o modificaremos el que viene por defecto. En la primera pestaña únicamente hay que darle un nombre y seleccionar la arquitectura sobre la que se puede aplicar esta plantilla:

En la siguiente pestaña se selecciona la tabla de partición que hemos creado anteriormente.

En installation media seleccionamos el mirror que también hemos creado antes:

En los templates en principio no hace falta modificar nada, aunque se podrían haber modificado para especificar configuraciones concretas, como el software que se debe instalar en cada servidor o configurar el proxy para las actualizaciones a través de YUM.

La última pestaña es la de parámetros. En mi caso añado la zona horaria que deberán tener mis servidores, aunque también se podría especificar en el provisioning template.

Una vez hemos terminado con esta plantilla ya estamos en disposición de empezar a desplegar sistemas automáticamente con solo unos clicks. En los próximos posts añadiré algunos ejemplos.

Jugando con Docker

Últimamente se esta oyendo mucho hablar de Docker. Se trata de una tecnología similar a la que ya existía en Solaris con las zonas, y en Linux con LXC (de hecho utiliza LXC por debajo). Parece que viene patrocinado por algunas de las grandes en internet como eBay, Spotify e incluso Google parece que venia utilizando algo parecido desde hace tiempo.
Docker
La gran ventaja, como en el caso de las zonas, es que te permite “virtualizar” sin depender de un hipervisor y con un overhead mínimo en comparación a la virtualización tradicional.

Instalación

Como todo en Linux es muy fácil de instalar y ya viene preparado en la mayoría de distribuciones. En el caso de CentOS hay que habilitar el repositorio EPEL editando el fichero de configuración del repositorio y poniendo la variable enabled a 1:

[root@centos1 ~]# vi /etc/yum.repos.d/epel.repo

[epel]
name=Extra Packages for Enterprise Linux 6 – $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
A continuación ya podemos instalar docker con yum. Como veremos, una de las dependencias es LXC:
[root@centos1 ~]# yum install docker-io
Dependencies Resolved

================================================================================
 Package            Arch            Version                 Repository     Size
================================================================================
Installing:
 docker-io          x86_64          1.0.0-3.el6             epel          4.5 M
Installing for dependencies:
 lxc                x86_64          0.9.0-2.el6             epel           78 k
 lxc-libs           x86_64          0.9.0-2.el6             epel          116 k

Transaction Summary
================================================================================
Install       3 Package(s)

Total download size: 4.7 M
Installed size: 24 M
Is this ok [y/N]: y

Así de sencillo es instalarlo. Y como vemos, la versión es la primera estable que se ha publicado recientemente:
[root@centos1 ~]# docker -v
Docker version 1.0.0, build 63fe64c/1.0.0
Para empezar a utilizarlo se debe iniciar el servicio y configurarlo para que arranque en el runlevel predeterminado:
[root@centos1 ~]# service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:                                                [  OK  ]
[root@centos1 ~]# chkconfig docker on

Imágenes y contenedores

Con el servicio ya en marcha podemos descargar las imágenes que docker mantiene, así como imágenes que la comunidad ha creado y ha subido. Por ejemplo descargaremos las últimas para centos y para ubuntu:

[root@centos1 ~]# docker pull centos:latest
Pulling repository centos
0c752394b855: Download complete
511136ea3c5a: Download complete
34e94e67e63a: Download complete

[root@centos1 ~]# docker pull ubuntu:latest
Pulling repository ubuntu
e54ca5efa2e9: Download complete
511136ea3c5a: Download complete
d7ac5e4f1812: Download complete
2f4b4d6a4a06: Download complete
83ff768040a0: Download complete
6c37f792ddac: Download complete
Para ver las imágenes que tenemos descargadas y disponibles para utilizar bastará con ejecutar el subcomando “images”:
[root@centos1 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              latest              e54ca5efa2e9        41 hours ago        276.1 MB
centos              latest              0c752394b855        10 days ago         124.1 MB
Pasando el parámetro -a podemos ver el historial de versiones de cada imagen:
[root@centos1 ~]# docker images -a
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              latest              e54ca5efa2e9        41 hours ago        276.1 MB
                            6c37f792ddac        41 hours ago        276.1 MB
                            83ff768040a0        41 hours ago        192.7 MB
                            2f4b4d6a4a06        41 hours ago        192.7 MB
                            d7ac5e4f1812        41 hours ago        192.5 MB
centos              latest              0c752394b855        10 days ago         124.1 MB
                            34e94e67e63a        2 weeks ago         0 B
                            511136ea3c5a        12 months ago       0 B
Podremos arrancar instancias o contenedores con las imágenes que queramos de la siguiente manera:
[root@centos1 ~]# docker run -i -t centos /bin/bash
bash-4.1# more /etc/centos-release
CentOS release 6.5 (Final)
bash-4.1# hostname
3ce460cbb9d8

[root@centos1 ~]# docker run -i -t ubuntu /bin/bash
root@60d6e0455be0:/# more /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION=”Ubuntu 14.04 LTS”
root@60d6e0455be0:/# hostname
60d6e0455be
Al pasar el parámetro -i al comando run se ejecutará el contenedor de forma interactiva, de forma que, en cuanto termine el comando que pasamos como parámetro la ejecución del contenedor terminará.
Mientras estemos ejecutando la shell, veremos que el contenedor está ejecutándose:
[root@centos1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
49087a343e7f        centos:latest       /bin/bash           12 seconds ago      Up 11 seconds                           dreamy_curie   
Si quisiesemos ver un historial de las instancias ejecutadas pasaríamos el parámetro -a:
 [root@centos1 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
15dc7c59189c        centos:latest       /bin/bash           27 seconds ago      Up 26 seconds                                   compassionate_fermi  
49087a343e7f        centos:latest       /bin/bash           12 minutes ago      Exited (0) 17 seconds ago                       dreamy_curie         
9e69f5b64254        ubuntu:latest       uname -r            15 minutes ago      Exited (0) 15 minutes ago                       high_engelbart       
f5aa352a5ce9        centos:latest       uname -r            15 minutes ago      Exited (0) 15 minutes ago                       jovial_meitner       
60d6e0455be0        ubuntu:latest       /bin/bash           17 minutes ago      Exited (0) 16 minutes ago                       cocky_leakey         
961b10b9bbbf        ubuntu:latest       hostname            17 minutes ago      Exited (0) 17 minutes ago                       insane_mayer         
3ce460cbb9d8        centos:latest       /bin/bash           19 minutes ago      Exited (0) 17 minutes ago                       loving_yonath  
Si por contra, quisiesemos ejecutar un contenedor en background o demonizado, como sucede en Solaris con las zonas, al comando run le pasaríamos el parámetro -d. En el siguiente ejemplo arrancaríamos una instancia de la imagen ubuntu y dos instancias de la imagen de centos y finalmente veríamos que se están ejecutando las tres:
[root@centos1 ~]# docker run -d -t ubuntu  /bin/bash
abc254ab2e8eb392ce80938c8f2b8fa8cb1603ab6935b2121b7cb0cddbdd64c3
[root@centos1 ~]# docker run -d -t centos  /bin/bash
59adfe1998cc678cf2c9db964f1b57e60a301ffa2139c7a4635ebe315db2b718
[root@centos1 ~]# docker run -d -t centos  /bin/bash
6714217732adadec19f47399fe5f7252823787869a96e8fed72457cd5106589c
[root@centos1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6714217732ad        centos:latest       /bin/bash           3 seconds ago       Up 2 seconds                            romantic_shockley 
59adfe1998cc        centos:latest       /bin/bash           7 seconds ago       Up 6 seconds                            thirsty_bartik    
abc254ab2e8e        ubuntu:latest       /bin/bash           14 seconds ago      Up 13 seconds                           naughty_yonath 
Al arrancar cada contenedor nos devuelve un número muy largo. Este número es el container_id que mas adelante vemos en la primera columna del comando ps. La última columna es un nombre que se asigna automáticamente y servirá para identificar las instancias de una forma mas amigable. Para parar las zonas que están corriendo podríamos pasar como identificador tanto el container_id como el nombre:

[root@centos1 ~]# docker stop romantic_shockley
romantic_shockley
[root@centos1 ~]# docker stop thirsty_bartik
thirsty_bartik
[root@centos1 ~]# docker stop naughty_yonath
naughty_yonath
[root@centos1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 

Como vemos, el kernel que se está ejecutando es el del host:

[root@centos1 ~]# uname -r
2.6.32-431.el6.x86_64
[root@centos1 ~]# docker run -i -t centos uname -r
2.6.32-431.el6.x86_64
[root@centos1 ~]# docker run -i -t ubuntu uname -r
2.6.32-431.el6.x86_64

Otra forma de arrancar un contenedor es con el comando start y pasando como parámetro el id del contenedor o el nombre que docker le asigno en su momento (lo podemos encontrar con docker ps -a)
 [root@centos1 ~]# docker start romantic_shockley
romantic_shockley
[root@centos1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
6714217732ad        centos:latest       /bin/bash           15 minutes ago      Up 3 seconds                            romantic_shockley
Para acceder a la consola del contenedor ejecutaríamos el comando attach:
 [root@centos1 ~]# docker attach romantic_shockley

Obtener información

Existe una serie de comandos que nos servirán para obtener información, tanto de docker, como de las imagenes o contenedores que tenemos creados. El comando info nos devolverá información general de la instalación actual de docker:
[root@centos1 ~]# docker info
Containers: 6
Images: 8
Storage Driver: devicemapper
 Pool Name: docker-8:1-132310-pool
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 784.9 Mb
 Data Space Total: 102400.0 Mb
 Metadata Space Used: 1.4 Mb
 Metadata Space Total: 2048.0 Mb
Execution Driver: native-0.2
Kernel Version: 2.6.32-431.el6.x86_64
Con el comando history veremos el historial de versiones de la imagen que le hayamos especificado:
[root@centos1 ~]# docker history centos
IMAGE               CREATED             CREATED BY                                      SIZE
0c752394b855        10 days ago         /bin/sh -c #(nop) ADD file:ce8fdb737386beb5fd   124.1 MB
34e94e67e63a        2 weeks ago         /bin/sh -c #(nop) MAINTAINER The CentOS Proje   0 B
511136ea3c5a        12 months ago                                                       0 B
También tendremos el comando inspect, que nos devolverá un objeto JSON con información detallada de la imagen. Tambien sirve para obetner información de un contenedor.

[root@centos1 ~]# docker inspect centos
[{
    “Architecture”: “amd64”,
    “Author”: “The CentOS Project \u003ccloud-ops@centos.org\u003e – ami_creator”,
    “Comment”: “”,
    “Config”: {
        “AttachStderr”: false,
        “AttachStdin”: false,
        “AttachStdout”: false,
        “Cmd”: null,
        “CpuShares”: 0,
        “Cpuset”: “”,
        “Domainname”: “”,
        “Entrypoint”: null,
        “Env”: [
            “HOME=/”,
            “PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”
        ],
        “ExposedPorts”: null,
        “Hostname”: “b2d0f1281acd”,
        “Image”: “34e94e67e63a0f079d9336b3c2a52e814d138e5b3f1f614a0cfe273814ed7c0a”,
        “Memory”: 0,
        “MemorySwap”: 0,
        “NetworkDisabled”: false,
        “OnBuild”: [],
        “OpenStdin”: false,
        “PortSpecs”: null,
        “StdinOnce”: false,
        “Tty”: false,
        “User”: “”,
        “Volumes”: null,
        “WorkingDir”: “”
    },
    “Container”: “b2d0f1281acd040292b36f6623feca10a89df1637c8d86e54079d473da4d05e3”,
    “ContainerConfig”: {
        “AttachStderr”: false,
        “AttachStdin”: false,
        “AttachStdout”: false,
        “Cmd”: [
            “/bin/sh”,
            “-c”,
            “#(nop) ADD file:ce8fdb737386beb5fd9aff7c9bbe9e6c9e60db290809dd6407c61b377e444b59 in /”
        ],
        “CpuShares”: 0,
        “Cpuset”: “”,
        “Domainname”: “”,
        “Entrypoint”: null,
        “Env”: [
            “HOME=/”,
            “PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin”
        ],
        “ExposedPorts”: null,
        “Hostname”: “b2d0f1281acd”,
        “Image”: “34e94e67e63a0f079d9336b3c2a52e814d138e5b3f1f614a0cfe273814ed7c0a”,
        “Memory”: 0,
        “MemorySwap”: 0,
        “NetworkDisabled”: false,
        “OnBuild”: [],
        “OpenStdin”: false,
        “PortSpecs”: null,
        “StdinOnce”: false,
        “Tty”: false,
        “User”: “”,
        “Volumes”: null,
        “WorkingDir”: “”
    },
    “Created”: “2014-06-09T21:38:41.281490617Z”,
    “DockerVersion”: “0.10.0”,
    “Id”: “0c752394b855e8f15d2dc1fba6f10f4386ff6c0ab6fc6a253285bcfbfdd214f5”,
    “Os”: “linux”,
    “Parent”: “34e94e67e63a0f079d9336b3c2a52e814d138e5b3f1f614a0cfe273814ed7c0a”,
    “Size”: 124078508
}

Para obtener informacion específica de un contenedor especificaremos al comando inspect la clave que queremos que nos devuelva, como por ejemplo el hostname o la dirección IP:
[root@centos1 ~]# docker run -d -t centos  /bin/bash
d7e7938ab7e98ff8e2413179d5222201de6a0c66716b99aafb35a0805fbf279e
[root@centos1 ~]# docker  ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
d7e7938ab7e9        centos:latest       /bin/bash           11 seconds ago      Up 11 seconds                           nostalgic_newton   

[root@centos1 ~]# docker inspect -f ‘{{ .Config.Hostname }}’ nostalgic_newton
d7e7938ab7e9
[root@centos1 ~]# docker inspect -f ‘{{ .NetworkSettings.IPAddress }}’ nostalgic_newton
172.17.0.22

Borrado de contenedores

Para norrar contenedores utilizaremos el comando rm. Le podremos pasar un único identificador de contenedor o varios en el mismo comando:
[root@centos1 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
abc254ab2e8e        ubuntu:latest       /bin/bash           22 minutes ago      Exited (0) 18 minutes ago                        naughty_yonath      
90ae553f4384        centos:latest       /bin/bash           23 minutes ago      Exited (-1) 22 minutes ago                       ecstatic_mcclintock

[root@centos1 ~]# docker rm ecstatic_mcclintock naughty_yonath
ecstatic_mcclintock
naughty_yonath