Innanzitutto, ho sentito la necessità di pubblicare una nuova risposta a causa dei seguenti sottili problemi con le risposte esistenti e dopo aver ricevuto una domanda sul mio commento sulla risposta di @ qwertzguy . Ecco i problemi con le risposte attuali:
- La risposta accettata da @MatthieuCerda sicuramente non funziona in modo affidabile, almeno non su tutte le istanze VPC che ho verificato. (Nei miei casi, ottengo un nome VPC per
hostname -d
, che viene utilizzato per il DNS interno, non nulla con "amazonaws.com" in esso.)
- La risposta più votata da @qwertzguy non funziona su nuove istanze m5 o c5 , che non dispongono di questo file. Amazon trascura di documentare questo cambiamento di comportamento AFAIK, sebbene la pagina del documento su questo argomento reciti "... Se esiste / sys / hypervisor / uuid ...". Ho chiesto al supporto AWS se questo cambiamento fosse intenzionale, vedi sotto †.
- La risposta di @Jer non funziona necessariamente ovunque perché la
instance-data.ec2.internal
ricerca DNS potrebbe non funzionare. Su un'istanza VPC di Ubuntu EC2 che ho appena testato, vedo:
$ curl http://instance-data.ec2.internal
curl: (6) Could not resolve host: instance-data.ec2.internal
ciò causerebbe la conclusione errata del codice basato su questo metodo che non si trova su EC2!
- La risposta da utilizzare
dmidecode
da @tamale può funzionare, ma si basa sul fatto che a.) Disponendo della dmidecode
propria istanza e b.) Con capacità root o senza sudo
password all'interno del proprio codice.
- La risposta a check / sys / devices / virtual / dmi / id / bios_version di @spkane è pericolosamente fuorviante! Ho controllato un'Ubuntu 14.04 esempio m5, e ottenuto un
bios_version
di 1.0
. Questo file non è affatto documentato sul documento di Amazon , quindi non vorrei davvero fare affidamento su di esso.
- La prima parte della risposta di @ Chris-Montanaro per controllare un URL di terze parti inaffidabile e l'utilizzo
whois
sul risultato è problematica su diversi livelli. Nota l'URL suggerito in quella risposta è una pagina 404 in questo momento! Anche se avete fatto trovare un servizio di terze parti che ha fatto il lavoro, sarebbe comparativamente molto lenta (rispetto a controllare un file localmente) ed eventualmente incorrere in problemi di rate-limiting o problemi di rete, o, eventualmente, l'istanza EC2 non hanno nemmeno bisogno accesso alla rete esterna.
- Il secondo suggerimento nella risposta di @ Chris-Montanaro per controllare http://169.254.169.254/ è un po 'meglio, ma un altro commentatore osserva che altri fornitori di cloud rendono disponibile questo URL di metadati dell'istanza, quindi devi stare attento a evitare false positivi. Inoltre sarà ancora molto più lento di un file locale, ho visto questo controllo particolarmente lento (diversi secondi per tornare) su istanze pesantemente caricate. Inoltre, dovresti ricordare di passare un
-m
o un --max-time
argomento per arricciarlo per evitare che si blocchi per un tempo molto lungo, specialmente su un'istanza non EC2 in cui questo indirizzo può portare a nessun posto e bloccarsi (come nella risposta di @ algal ).
Inoltre, non vedo che nessuno abbia menzionato il fallback documentato di Amazon nel controllare il (possibile) file /sys/devices/virtual/dmi/id/product_uuid
.
Chi sapeva che determinare se si sta eseguendo su EC2 potrebbe essere così complicato ?! OK, ora che abbiamo (la maggior parte) dei problemi con gli approcci elencati elencati, ecco uno snippet bash suggerito per verificare se stai utilizzando EC2. Penso che questo dovrebbe funzionare generalmente su quasi tutte le istanze di Linux, le istanze di Windows sono un esercizio per il lettore.
#!/bin/bash
# This first, simple check will work for many older instance types.
if [ -f /sys/hypervisor/uuid ]; then
# File should be readable by non-root users.
if [ `head -c 3 /sys/hypervisor/uuid` == "ec2" ]; then
echo yes
else
echo no
fi
# This check will work on newer m5/c5 instances, but only if you have root!
elif [ -r /sys/devices/virtual/dmi/id/product_uuid ]; then
# If the file exists AND is readable by us, we can rely on it.
if [ `head -c 3 /sys/devices/virtual/dmi/id/product_uuid` == "EC2" ]; then
echo yes
else
echo no
fi
else
# Fallback check of http://169.254.169.254/. If we wanted to be REALLY
# authoritative, we could follow Amazon's suggestions for cryptographically
# verifying their signature, see here:
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
# but this is almost certainly overkill for this purpose (and the above
# checks of "EC2" prefixes have a higher false positive potential, anyway).
if $(curl -s -m 5 http://169.254.169.254/latest/dynamic/instance-identity/document | grep -q availabilityZone) ; then
echo yes
else
echo no
fi
fi
Ovviamente, è possibile espandere questo con ancora più controlli di fallback e includere la paranoia sulla gestione, ad esempio un falso positivo che si /sys/hypervisor/uuid
verifica per iniziare con "ec2" per caso e così via. Ma questa è una soluzione abbastanza buona per scopi illustrativi e probabilmente quasi tutti i casi d'uso non patologici.
[†] Ho ricevuto questa spiegazione dal supporto AWS sulla modifica per le istanze c5 / m5:
Le istanze C5 e M5 usano un nuovo stack hypervisor e i driver del kernel associati non creano file in sysfs (che è montato su / sys) come fanno i driver Xen usati dagli altri tipi di istanza / precedenti . Il modo migliore per rilevare se il sistema operativo è in esecuzione su un'istanza EC2 è tenere conto delle diverse possibilità elencate nella documentazione collegata .