EC2 인스턴스 인 호스트에서 일부 스크립트를 실행하고 싶지만 호스트가 실제로 EC2 인스턴스 인지 확인하는 방법을 모르겠습니다 .
몇 가지 테스트를했지만 충분하지 않습니다.
- 바이너리 ec2_userdata가 사용 가능한지 테스트하십시오 (그러나 항상 해당되는 것은 아님).
- " http://169.254.169.254/latest/meta-data "의 가용성을 테스트하십시오.
EC2 인스턴스 인 호스트에서 일부 스크립트를 실행하고 싶지만 호스트가 실제로 EC2 인스턴스 인지 확인하는 방법을 모르겠습니다 .
몇 가지 테스트를했지만 충분하지 않습니다.
답변:
실제로 호스트가 EC2 인스턴스인지 감지하는 매우 간단한 방법이 있습니다. 퍼블릭 IP의 역방향 조회를 확인하십시오. EC2 반전은 놓치기 매우 어렵습니다.
또한 수정하지 않은 경우 호스트 이름이 반대로되어 더 쉽게 찾을 수 있습니다.
EC2 인스턴스 태그를 가져 오는 표준 방법이므로 실제로 "매직 IP"를 사용할 수도 있지만 EC2 네트워크에 있지 않은 경우 일반적으로 그렇지 않은 타임 아웃을 기다려야합니다. 바람직한...
이러한 방법으로 충분하지 않은 경우 IP를 만든 후 Amazon EC2 IP 블록 내에 있는지 확인하십시오.
편집 :이 작은 쉘 비트를 사용할 수 있습니다 :
#!/bin/bash
LOCAL_HOSTNAME=$(hostname -d)
if [[ ${LOCAL_HOSTNAME} =~ .*\.amazonaws\.com ]]
then
echo "This is an EC2 instance"
else
echo "This is not an EC2 instance, or a reverse-customized one"
fi
하지만 [[는 bashism입니다. Python 또는 Perl uniline YMMV를 사용할 수도 있습니다.
hostname -d
반환eu-west-1.compute.internal
오류 메시지를 피하고 스크립트에 사용 예를 포함시키기 위해 Hannes의 답변을 변경했습니다.
if [ -f /sys/hypervisor/uuid ] && [ `head -c 3 /sys/hypervisor/uuid` == ec2 ]; then
echo yes
else
echo no
fi
Windows 인스턴스에서는 작동하지 않습니다. 컬에 비해 이점은 EC2와 비 EC2 모두에서 순간에 가깝다는 것입니다.
ec2
은 오 탐지로 시작하는 UUID를 생성 할 수 있습니다. 해당 파일을 채우는 하이퍼 바이저를 사용하는 경우에만 (256-in-256 기회) 가능성은 없습니다. 그렇기 때문에 위에 링크 된 설명서에 " EC2 인스턴스를보고 있을 것 "이라고 나와 있습니다.
먼저 기존 답변에 대한 다음과 같은 미묘한 문제로 인해 @qwertzguy의 답변에 대한 내 의견에 대한 질문을받은 후 새로운 답변을 게시해야한다고 생각했습니다 . 현재 답변과 관련된 문제는 다음과 같습니다.
hostname -d
에는 "amazonaws.com"이없는 내부 DNS에 사용되는에 대한 VPC 이름을 얻 습니다.)instance-data.ec2.internal
. 방금 테스트 한 Ubuntu EC2 VPC 인스턴스
$ curl http://instance-data.ec2.internal
curl: (6) Could not resolve host: instance-data.ec2.internal
에서이 방법에 의존하는 코드가 EC2에 있지 않다고 잘못 판단하게됩니다!dmidecode
하는 대답 은 효과가있을 수 있지만 a.) dmidecode
인스턴스에서 사용할 수 있고 b.) sudo
코드 내에서 루트 또는 암호가없는 기능 이 있어야 합니다.bios_version
의 1.0
. 이 파일은 Amazon의 doc에 전혀 문서화되어 있지 않으므로 실제로 의존하지는 않습니다.whois
여러 수준에서 문제가 있습니다. 해당 답변에서 제안 된 URL은 현재 404 페이지입니다. 당신이 일을했던 제 3 자 서비스를 발견했다하더라도, 그것은 비교적 것이 매우 (로컬 파일을 확인 비해) 느리고 가능 속도 제한 문제 또는 네트워크 문제로 실행, 또는 아마도 당신의 EC2 인스턴스도 가지고 있지 않습니다 외부 네트워크 액세스.-m
또는 --max-time
인수 를 전달 해야합니다 .또한 (가능한) 파일 확인에 대한 아마존의 문서화 된 폴백을 언급 한 사람은 아무도 없습니다 /sys/devices/virtual/dmi/id/product_uuid
.
EC2에서 실행 중인지 판단하는 것이 너무 복잡하다는 것을 누가 알았습니까?! 이제 나열된 접근법에 대한 문제가 대부분 있었으므로 EC2에서 실행 중인지 확인하기 위해 제안 된 bash 스 니펫이 있습니다. 나는 이것이 거의 모든 Linux 인스턴스에서 일반적으로 작동해야한다고 생각합니다 .Windows 인스턴스는 독자에게 연습입니다.
#!/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
분명히, 더 많은 폴백 검사를 통해이를 확장 할 수 /sys/hypervisor/uuid
있으며 우연히 "ec2"로 시작 하는 오 탐지 등의 처리에 대한 편집증을 포함시킬 수 있습니다. 그러나 이것은 예시 목적으로 사용되며 거의 모든 병리학 적 사용 사례에 대한 충분한 솔루션입니다.
[†] c5 / m5 인스턴스 변경에 대한 AWS 지원의 설명을 다음에서 확인하십시오.
C5 및 M5 인스턴스는 새로운 하이퍼 바이저 스택 을 사용하며 관련 커널 드라이버는 다른 / 이전 인스턴스 유형에서 사용 하는 Xen 드라이버가 그렇듯이 sysfs (/ sys에 마운트 됨)에 파일을 만들지 않습니다 . 운영 체제가 EC2 인스턴스에서 실행 중인지 여부를 감지하는 가장 좋은 방법은 연결 한 설명서에 나열된 다양한 가능성을 설명하는 것 입니다.
elif
블록 위의 주석이 말한 것이므로 elif
테스트에서 -r
테스트 연산자를 사용 하여 파일이 있는지 여부와 파일에 대한 읽기 권한이 있는지 확인합니다.
IP 대신 EC2 내부 도메인 이름으로 메타 데이터를 찾으십시오. 그러면 EC2에 있지 않은 경우 빠른 DNS 오류가 발생하고 IP 충돌 또는 라우팅 문제가 발생하지 않습니다.
curl -s http://instance-data.ec2.internal && echo "EC2 instance!" || echo "Non EC2 instance!"
일부 배포판에서는 매우 기본적인 시스템 또는 설치 단계 초기에 컬을 사용할 수 없습니다. 사용 wget과 대신 :
wget -q http://instance-data.ec2.internal && echo "EC2 instance!" || echo "Non EC2 instance!"
목표가 EC2 인스턴스인지 아니면 Google과 같은 다른 종류의 클라우드 인스턴스인지를 알리는 것이라면 dmidecode
매우 잘 작동하며 네트워킹이 필요하지 않습니다. EC2와 GCE의 메타 데이터 URL 경로가 다르기 때문에 다른 접근 방식과 비교하여이 방법을 선호합니다.
# From a google compute VM
$ sudo dmidecode -s bios-version
Google
# From an amazon ec2 VM
$ sudo dmidecode -s bios-version
4.2.amazon
1.0
아무것도 언급하지 않습니다 amazon
.
호스트 이름이 변경 될 수 있습니다. 퍼블릭 IP에 대해 whois를 실행하십시오.
if [[ ! -z $(whois $(curl -s shtuff.it/myip/short) | grep -i amazon) ]]; then
echo "I'm Amazon"
else
echo "I'm not Amazon"
fi
또는 AWS 메타 데이터 URL을 누르십시오
if [[ ! -z $(curl -s http://169.254.169.254/1.0/) ]]; then
echo "I'm Amazon"
else
echo "I'm not Amazon"
fi
이것은 ec2의 Linux 호스트에서도 잘 작동하며 네트워크 및 관련 시간 초과가 필요하지 않습니다.
grep -q amazon /sys/devices/virtual/dmi/id/bios_version
아마존 이이 항목을 다음과 같이 정의하기 때문에 작동합니다.
$ cat /sys/devices/virtual/dmi/id/bios_version
4.2.amazon
1.0
. 에 대한 언급이 없습니다 amazon
.
test -f /sys/hypervisor/uuid -a `head -c 3 /sys/hypervisor/uuid` == ec2 && echo yes
그러나 나는 이것이 배포판에서 얼마나 이식 가능한지 모르겠다.
빠른 답변 :
if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]] && \
grep -q "^EC2" /sys/devices/virtual/dmi/id/product_uuid
then
echo "IS EC2"
else
echo "NOT EC2"
fi
나는 1 년 넘게 여기에 게시 된 답변 중 하나를 사용했지만 새로운 'c5'인스턴스 유형에서는 작동하지 않습니다 (지금 'c4'에서 업그레이드하는 중입니다).
나는이 솔루션이 나중에 깨질 가능성이 가장 적은 것처럼 보이기 때문에 좋아합니다.
이전 인스턴스 유형과 최신 인스턴스 유형에서이 파일은 존재하며 'EC2'로 시작합니다. VirtualBox에서 실행중인 Ubuntu를 확인했으며 (지원해야 함) 문자열 'VirtualBox'가 포함되어 있습니다.
이전 포스터에서 언급했듯이 (그러나 놓치기 쉬웠습니다.)이 작업을 수행하는 방법에 대한 Amazon 설명서가 있습니다.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
아마도 당신은 "facter"를 사용할 수 있습니다 :
"Facter는 운영 체제, Linux 배포판 또는 MAC 주소와 같은 간단한 운영 체제 사실을 검색하기위한 크로스 플랫폼 라이브러리입니다."
http://www.puppetlabs.com/puppet/related-projects/facter/
예를 들어, ec2 팩트 (fact-1.6.12 / lib / facter / ec2.rb)를 살펴보면 다음과 같습니다.
require 'facter/util/ec2'
require 'open-uri'
def metadata(id = "")
open("http://169.254.169.254/2008-02-01/meta-data/#{id||=''}").read.
split("\n").each do |o|
key = "#{id}#{o.gsub(/\=.*$/, '/')}"
if key[-1..-1] != '/'
value = open("http://169.254.169.254/2008-02-01/meta-data/#{key}").read.
split("\n")
symbol = "ec2_#{key.gsub(/\-|\//, '_')}".to_sym
Facter.add(symbol) { setcode { value.join(',') } }
else
metadata(key)
end
end
end
def userdata()
begin
value = open("http://169.254.169.254/2008-02-01/user-data/").read.split
Facter.add(:ec2_userdata) { setcode { value } }
rescue OpenURI::HTTPError
end
end
if (Facter::Util::EC2.has_euca_mac? || Facter::Util::EC2.has_openstack_mac? ||
Facter::Util::EC2.has_ec2_arp?) && Facter::Util::EC2.can_connect?
metadata
userdata
else
Facter.debug "Not an EC2 host"
end
이 파티에 조금 늦었지만이 게시물을 보았고이 AWS 설명서를 찾았습니다.
EC2 인스턴스를 식별하는 결정적이고 암호로 검증 된 방법은 서명을 포함하여 인스턴스 자격 증명 문서를 확인하십시오. 이러한 문서는 모든 EC2 인스턴스에서 라우팅 할 수없는 로컬 주소 http://169.254.169.254/latest/dynamic/instance-identity/에서 제공됩니다.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
컬 타임 아웃을 다음과 같이 설정할 수는 있지만 네트워크 오버 헤드가 필요합니다.
curl -s --connect-timeout 5 http://169.254.169.254/latest/dynamic/instance-identity/
시간 초과가 5 초로 설정됩니다.