• Aucun résultat trouvé

SCRIPTS POUR SUIVRE L’ÉTAT DES RESSOURCES Télémétrer le CPU

Nous souhaitons avoir à intervalle de temps régulier le pourcentage de charge d’utilisation du CPU. L’intervalle de temps est fixé dans un fichier de configuration. Pour les conteneurs, les commandes Linux des CGroups nous permettent d’obtenir le temps total d’utilisation du CPU par un conteneur. Le détail de toutes les commandes possibles est disponible au chapitre 8.2.3 du guide Oracle Linux (Oracle). Pour avoir le pourcentage, nous relevons donc la charge d’utilisation du CPU à un instant t1 puis à un instant t2 et nous faisons la différence.

#!/bin/bash

# ${1} is the container's name # ${2} is the time for observation # ${3} is a computer constante # get the cpu usage a t=0

NSCPUNOW=`lxc-cgroup -n ${1} cpuacct.usage` # get the cpu usage a ${2} second later

sleep ${2}

NSCPUAFTER=`lxc-cgroup -n ${1} cpuacct.usage` # calculate the percentage of cpu usage

NSDIFFERENCE=`echo "$NSCPUAFTER $NSCPUNOW" | awk '{print $1-$2}'` TOTALTIME=$((${2}*1000000000))

RESULT=`echo "$NSDIFFERENCE $TOTALTIME" | awk '{print $1*100/$2}'` # save result in text file

HOUR=$(date +%H) MINUTE=$(date +%M) SECONDE=$(date +%S)

echo ""$HOUR:$MINUTE:$SECOND", $RESULT" >> ./result/containers-${1}-cpu.csv echo ""$HOUR:$MINUTE:$SECOND", $RESULT"

Pour l’hôte, Linux nous fournit une commande, mpstat, qui permet d’avoir pour chaque cœur de la machine physique son pourcentage d’utilisation. Il faut donc utiliser cette commande et récupérer la valeur correspondant à chaque cœur.

#!/bin/bash

# ${1} is the time for observation # ${2} is a computer constante

# get the number of computer processors

NBPROCESSOR=`cat /proc/cpuinfo | grep processor | wc -l` # to initialize the good line to get value

COUNTER=0

MAX=`echo "$NBPROCESSOR $COUNTER" | awk '{print $1+$2}'` # Initialization of arrays PREV_USER=() USER=() PREV_NICE=() NICE=() PREV_SYST=() SYST=() PREV_IDLE=() IDLE=() PREV_TOTAL=() TOTAL=()

while [ $COUNTER -lt $MAX ]; do

CPU=`cat /proc/stat | grep '^cpu'$COUNTER' '`

PREV_USER=("${PREV_USER[@]}" "`echo $CPU | awk '{print $2}'`") PREV_NICE=("${PREV_NICE[@]}" "`echo $CPU | awk '{print $3}'`") PREV_SYST=("${PREV_SYST[@]}" "`echo $CPU | awk '{print $4}'`") PREV_IDLE=("${PREV_SYST[@]}" "`echo $CPU | awk '{print $5}'`")

let SUM=${PREV_USER[$COUNTER]}+${PREV_NICE[$COUNTER]}+${PREV_SYST[$COUNTER]} PREV_TOTAL=("${PREV_TOTAL[@]}" "$SUM") let COUNTER=COUNTER+1 done sleep ${1} COUNTER=0

while [ $COUNTER -lt $MAX ]; do

CPU=`cat /proc/stat | grep '^cpu'$COUNTER' '` USER=("${USER[@]}" "`echo $CPU | awk '{print $2}'`") NICE=("${NICE[@]}" "`echo $CPU | awk '{print $3}'`") SYST=("${SYST[@]}" "`echo $CPU | awk '{print $4}'`") IDLE=("${SYST[@]}" "`echo $CPU | awk '{print $5}'`")

let SUM=${USER[$COUNTER]}+${NICE[$COUNTER]}+${SYST[$COUNTER]} TOTAL=("${TOTAL[@]}" "$SUM")

let COUNTER=COUNTER+1 done

COUNTER=0

while [ $COUNTER -lt $MAX ]; do

# Calculate the CPU usage between two checked. let SLEEPTIME=${2}*${1} let "DIFF_TOTAL=${TOTAL[$COUNTER]}-${PREV_TOTAL[$COUNTER]}" let "DIFF_USAGE_IDLE=100*DIFF_TOTAL/$SLEEPTIME" let "DIFF_USER=${USER[$COUNTER]}-${PREV_USER[$COUNTER]}" let "DIFF_USAGE_USER=100*$DIFF_USER/$SLEEPTIME" let "DIFF_SYST=${SYST[$COUNTER]}-${PREV_SYST[$COUNTER]}"

let "DIFF_USAGE_SYST=100*$DIFF_SYST/$SLEEPTIME" # incremente and number to save

let COUNTER=COUNTER+1 # Save result in text file

RESULT=`echo $RESULT$DIFF_USAGE_IDLE+` HOUR=$(date +%H)

MINUTE=$(date +%M) SECOND=$(date +%S)

echo ""$HOUR:$MINUTE:$SECOND", $DIFF_USAGE_USER" >> ./result/host-cpu-$COUNTER-usr.csv echo ""$HOUR:$MINUTE:$SECOND", $DIFF_USAGE_SYST" >> ./result/host-cpu-$COUNTER-sys.csv echo ""$HOUR:$MINUTE:$SECOND", $DIFF_USAGE_IDLE" >> ./result/host-cpu-$COUNTER.csv done

echo ""$HOUR:$MINUTE:$SECOND", $RESULT"

Télémétrer la mémoire

Nous souhaitons avoir à intervalle de temps régulier l’utilisation de la mémoire par les conteneurs. Nous retrouvons au chapitre 8.2.8 du guide Oracle Linux (Oracle) la commande à utiliser. Elle nous renvoie la mémoire, en octets, utilisée par un conteneur. Il nous suffira ensuite de récupérer la capacité totale en mémoire de la machine physique pour calculer le pourcentage d’utilisation de cette dernière par le conteneur étudié.

#!/bin/bash

# ${1} is the container's name # computer memory

TOTALCOMPUTER=`free -b | awk '$2 {print $2}' | awk 'NR==2'` # memory use by the container

USEDCONTAINER=`lxc-cgroup -n ${1} memory.usage_in_bytes` # percentage

RESULT=$USEDCONTAINER # save result in text file

HOUR=$(date +%H) MINUTE=$(date +%M) SECOND=$(date +%S)

echo ""$HOUR:$MINUTE:$SECOND", $RESULT" >> ./result/containers-${1}-memory.csv echo ""$HOUR:$MINUTE:$SECOND", $RESULT"

Télémétrer la bande passante

La dernière ressource de bas niveau que nous souhaitons télémétrer est le nombre d’octets lu et écrit sur le réseau par chaque conteneur et par l’hôte.

Dans les deux cas, la commande Linux ifconfig a été utilisée, car elle donne l’information souhaitée pour toutes les interfaces de la machine physique. Il a seulement fallu, avant

d’exécuter cette commande, récupérer le nom de l’interface pour chaque instance que nous souhaitons observer. Pour les conteneurs, une commande des CGroups, lxc-info, permet de récupérer de nombreuses informations sur un conteneur, dont le nom de son interface.

#!/bin/bash

# ${1} is the container's name # ${2} is the time for observation # save result in text file

HOUR=$(date +%H) MINUTE=$(date +%M) SECOND=$(date +%S) # get the interface network # monitor at t = 0

RX0=`lxc-attach -n ${1} ifconfig eth0 | grep "RX bytes" | cut -d: -f2 | awk '{ print $1 }'` TX0=`lxc-attach -n ${1} ifconfig eth0 | grep "TX bytes" | cut -d: -f3 | awk '{ print $1 }'` # wait TIME_MONITORING seconds

SLEEP=`echo "${2}" | awk '{print $1/2}'` sleep $SLEEP

# monitor at t = t+TIME_MONITORING

RX1=`lxc-attach -n ${1} ifconfig eth0 | grep "RX bytes" | cut -d: -f2 | awk '{ print $1 }'` TX1=`lxc-attach -n ${1} ifconfig eth0 | grep "TX bytes" | cut -d: -f3 | awk '{ print $1 }'` RX=`echo "$RX1 $RX0 $SLEEP" | awk '{print ($1-$2)/$3}'`

TX=`echo "$TX1 $TX0 $SLEEP" | awk '{print ($1-$2)/$3}'`

echo ""$HOUR:$MINUTE:$SECOND", $RX" >> ./result/containers-${1}-Rx-network.csv echo ""$HOUR:$MINUTE:$SECOND", $TX" >> ./result/containers-${1}-Tx-network.csv echo ""$HOUR:$MINUTE:$SECOND", $RX+$TX"

Pour l’hôte, la première étape a été de lancer une commande permettant de trouver l’adresse IP de la machine. Ensuite, à partir de cette adresse, le nom de l’interface a pu être retrouvé. L’adresse IP a été trouvée grâce au code python suivant :

ipaddress = [(s.connect(('8.8.8.8', 80)), s.getsockname()[0], s.close()) for s in