AWS permite crear snapshots de los volúmenes EBS que tengamos bajo nuestro control. Estos son algunos de los detalles al respecto:
- Se almacenan en S3, por lo tanto la durabilidad y disponibilidad de los mismos es mas que razonable.
- Son incrementales, por lo tanto son eficientes en espacio y tiempo.
- Restaurar un snapshot es muy sencillo, simplemente hay que crear un nuevo volumen del snapshot.
En casos donde detener la instancia o desmontar los volúmenes no sea posible se puede optar por congelar el sistema de archivos durante la creación del snapshot haciendo uso de xfs_freeze.
xfs_freeze permite detener las operaciones de escrituras sobre un sistema de archivos (-f), y luego retomarlas (-u).
En este post se va a describir una prueba de concepto de como se puede lograr un snapshot consistente deteniendo las operaciones de escritura sobre el volumen.Role IAM para las instancias
Para poder tomar los snapshots de manera automática y desde las mismas instancias debemos permitirles ciertas operaciones (API calls) como CreateSnapshot, DescribeInstances y DescribeSnapshots. Para lograr esta parte podemos valernos de un Role IAM y adjuntarle la siguiente Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1447448059000",
"Effect": "Allow",
"Action": [
"ec2:CreateSnapshot",
"ec2:DescribeInstances",
"ec2:DescribeSnapshots"
],
"Resource": [
"*"
]
}
]
}
El rol nos permitirá darle a las instancias la capacidad de acceder a este subconjunto de la API sin tener que preocuparnos por mantener las credenciales.
Una vez creado el rol las instancias deben lanzarse utilizando dicho rol. Para comprobar que el rol se encuentra aplicado a la instancia correctamente podemos hacer lo siguiente:
[ec2-user@ip-172-31-20-132 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
EC2-BackupRole
[ec2-user@ip-172-31-20-132 ~]$
Se puede ver que el role EC2-BackupRole se encuentra asociado a la instancia. Para comprobar la autorización podemos, por ejemplo, describir el volumen del que tomaremos el snapshot:
[ec2-user@ip-172-31-20-132 ~]$ aws ec2 describe-instances --instance-ids i-8161a338 --query 'Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==`/dev/sdb`]' --output json
[
{
"DeviceName": "/dev/sdb",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": false,
"VolumeId": "vol-e3490220",
"AttachTime": "2015-11-14T10:28:41.000Z"
}
}
]
[ec2-user@ip-172-31-20-132 ~]$
Script para la creación de los snapshots
Una vez solucionada la parte de la autorización con IAM, sólo queda escribir el script que cree los snapshots. Los siguientes puntos se tendrán en cuenta:
- El script debe crear un snapshot del volumen /dev/sdb, o cualquiera sea el volumen en cuestión.
- El snapshot debe ser consistente. Por lo tanto debe detener las operaciones de escritura.
- Se debe poder definir un timeout que permita recuperar las operaciones de escritura en caso de que la creación del snapshot demore demasiado tiempo. Por supuesto, esto pone en riesgo la integridad del snapshot, pero garantiza que se conocerá el tiempo máximo que el servicio se encontrará degradado (sin posibilidades de escribir).
#!/bin/bash VOLUME='/dev/sdb' MOUNT='/mnt' LOGS=/var/log/backups.log DONE=0 TIMEOUT=300 TIMEDOUT=0 SLEEP=30 INSTANCEID=`curl http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null` REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document 2>/dev/null | grep region | awk -F\" '{print $4}'` VOLUMEID=`aws ec2 describe-instances --instance-ids $INSTANCEID --region $REGION --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName=='$VOLUME'].Ebs.{ID:VolumeId}" --output text` DESCRIPTION="$INSTANCEID-$VOLUMEID-$(date +%F)" echo "$(date) Iniciando backup de: $INSTANCEID $REGION $VOLUMEID" #Detener los servicios que quieras detener aqui ### sync xfs_freeze -f $MOUNT echo "$(date) Escrituras detenidas." SNAPSHOTID=`aws ec2 create-snapshot --volume-id $VOLUMEID --region $REGION --description $DESCRIPTION --query '{ID:SnapshotId}' --output text` OUT=$? if [ $OUT -ne 0 ]; then echo "$(date) La creacion del snapshot fallo." xfs_freeze -u $MOUNT echo "$(date) Escrituras reestablecidas." exit fi while [ $DONE = "0" ]; do PROGRESS=`aws ec2 describe-snapshots --snapshot-id $SNAPSHOTID --region $REGION --query 'Snapshots[0].{Progress:Progress}' --output text` OUT=$? if [ $OUT -ne 0 ]; then echo "$(date) Snapshot $SNAPSHOTID aun no esta disponible." sleep $SLEEP TIMEOUT=`echo "$TIMEOUT-$SLEEP" | bc` else if [ $PROGRESS = "100%" ]; then DONE="1" echo "$(date) Snapshot $SNAPSHOTID listo" else echo "$(date) Snapshot $SNAPSHOTID $PROGRESS" sleep $SLEEP TIMEOUT=`echo "$TIMEOUT-$SLEEP" | bc` fi fi if [ $TIMEOUT -le 0 ]; then DONE="1" TIMEDOUT="1" fi done xfs_freeze -u $MOUNT echo "$(date) Escrituras reestablecidas." if [ $TIMEDOUT = "1" ]; then echo "$(date) Snapshot $SNAPSHOTID timed out!!! Podria ser inconsistente" else echo "$(date) Snapshot $SNAPSHOTID terminado exitosamente" fi
Prueba 1: Primer snapshot
Dada la naturaleza incremental de los snapshots, mientras mas bloques "Sucios" haya por copiar mas va a demorar el snapshot. Esto se hace mas evidente generalmente en el primer snapshot que se tome de un volumen.
Lanzamos una escritura aleatoria en background de unos 12GB de la siguiente manera
[ec2-user@ip-172-31-20-132 ~]$ sudo dd if=/dev/urandom of=/mnt/archivo_borrar bs=1M count=12000 &
[2] 4783
[ec2-user@ip-172-31-20-132 ~]$
cuando llevan escritos unos 8GB
[ec2-user@ip-172-31-20-132 ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/xvda1 7.8G 1.1G 6.6G 15% /
devtmpfs 3.9G 60K 3.9G 1% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
/dev/xvdb 99G 8.4G 85G 9% /mnt
[ec2-user@ip-172-31-20-132 ~]$
lanzamos el snapshot
[ec2-user@ip-172-31-20-132 ~]$ sudo ./backups.sh
Sat Nov 14 17:13:24 UTC 2015 Iniciando backup de: i-8161a338 eu-west-1 vol-e3490220
Sat Nov 14 17:13:26 UTC 2015 Escrituras detenidas.
Sat Nov 14 17:13:26 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:13:57 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:14:27 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:14:58 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:15:28 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:15:58 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:16:29 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:16:59 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:17:30 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:18:00 UTC 2015 Snapshot snap-27582071 0%
Sat Nov 14 17:18:30 UTC 2015 Escrituras reestablecidas.
Sat Nov 14 17:18:30 UTC 2015 Snapshot snap-27582071 timed out!!! Podria ser inconsistente
[ec2-user@ip-172-31-20-132 ~]$
este primer snapshot no pudo terminar en el lapso de los 300 segundos, por lo tanto podría tratarse de un snapshot inconsistente.
Poco antes de lanzar la creación del snapshot, en una segunda consola puse a correr iostat para ver el comportamiento de las operaciones de escritura, aquí están los resultados:
[ec2-user@ip-172-31-20-132 ~]$ sudo iostat -x -d /dev/xvdb 5 30
Linux 4.1.10-17.31.amzn1.x86_64 (ip-172-31-20-132) 11/14/2015 _x86_64_ (2 CPU)
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 10.24 0.12 78.65 1.00 20046.09 254.48 9.79 124.28 0.92 7.27
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 1.60 0.00 637.40 0.00 163038.40 255.79 84.64 132.79 0.95 60.24
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.20 0.00 0.40 0.00 4.80 12.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.20 0.00 54.80 0.00 13931.20 254.22 4.92 55.08 0.64 3.52
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 2.40 0.00 171.60 0.00 43056.00 250.91 21.20 134.67 0.95 16.32
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
...
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.00 0.00 0.20 0.00 1.60 8.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.80 0.00 101.40 0.00 25816.00 254.60 7.65 75.46 0.78 7.92
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.80 0.00 0.40 0.00 9.60 24.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
xvdb 0.00 0.20 0.00 0.40 0.00 4.80 12.00 0.00 0.00 0.00 0.00
^C[ec2-user@ip-172-31-20-132 ~]$
se puede ver la linea en negrita (azul), como a partir de ese punto no hay mas operaciones de escritura sobre el disco. Los altos valores de escrituras en ese momento se deben a las operaciones sync y xfs_freeze. Las operaciones de escritura se re establecen mas adelante (también en negrita, roja) cuando el timeout se cumple en el script.
Prueba 2: Segundo snapshot
El segundo snapshot termina antes del timeout, por lo que se lo puede considerar aboslutamente consistente.
[ec2-user@ip-172-31-20-132 ~]$ sudo ./backups.sh
Sat Nov 14 18:14:26 UTC 2015 Iniciando backup de: i-8161a338 eu-west-1 vol-e3490220
Sat Nov 14 18:14:26 UTC 2015 Escrituras detenidas.
Sat Nov 14 18:14:27 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:14:57 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:15:27 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:15:58 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:16:28 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:16:59 UTC 2015 Snapshot snap-39405312 0%
Sat Nov 14 18:17:29 UTC 2015 Snapshot snap-39405312 listo
Sat Nov 14 18:17:29 UTC 2015 Escrituras reestablecidas.
Sat Nov 14 18:17:29 UTC 2015 Snapshot snap-39405312 terminado exitosamente
[ec2-user@ip-172-31-20-132 ~]$
Resumen
Esto es una simple prueba de concepto y no fue realmente probado en ambientes de producción. Desde mis pruebas puedo decir que dd (el proceso bloqueado por xfs_freeze) no sufrió mas que el bloqueo que era de esperarse, posiblemente esto no sea tan factible en una partición donde trabaja una BD que realiza muchos inserts por ejemplo. El script podría lanzarse sencillamente desde un cronjob y tendriamos todo automatizado y aceitado!!!
No hay comentarios:
Publicar un comentario