ec2-metadata icon indicating copy to clipboard operation
ec2-metadata copied to clipboard

HTTPConnectionPool(host='169.254.169.254') timeout in docker bridge mode

Open luuthang2011 opened this issue 3 years ago • 10 comments

Python Version

3.9.13

Package Version

2.10.0

Description

I tried use ec2-metadata inside docker container with bridge mode. Curl "169.254.169.254" got ok but ec2-metadata raised error "requests.exceptions.ReadTimeout: HTTPConnectionPool(host='169.254.169.254', port=80): Read timed out. (read timeout=5.0)"

image

luuthang2011 avatar Aug 04 '22 04:08 luuthang2011

I need more information. I've never used a docker container with bridge mode. There shouldn't be anything fundamentally different between curl and python... Can you try using netcat, or opening a raw socket in python?

adamchainz avatar Aug 04 '22 07:08 adamchainz

I can connect to 169.254.169.254 with curl or netcat or python urllib.request from docker container in bridge mode. Ec2-metadata works well with --network host.

image

luuthang2011 avatar Aug 04 '22 08:08 luuthang2011

can you provide a way to recreate this? otherwise I can do no more.

adamchainz avatar Aug 05 '22 14:08 adamchainz

I can recreate the issue as follow:

  • Run a docker container on EC2 with default network config such as "docker run -it python bash"
  • Install ec2-medata
  • Try to get metadata using python

image

luuthang2011 avatar Aug 08 '22 02:08 luuthang2011

I am facing the same issue. Any resolution/work around for this?

Chitz avatar Sep 15 '22 11:09 Chitz

I am getting metadata from ip 169.254.169.254 using requests.

ec2_metadata = requests.get('http://169.254.169.254/latest/dynamic/instance-identity/document').json()

luuthang2011 avatar Sep 15 '22 13:09 luuthang2011

If requests works, this package should work, as it's only a thin layer around requests - see the code:

https://github.com/adamchainz/ec2-metadata/blob/70d1ecdae9a86acaeb8005d353e0cfc53ffdf628/src/ec2_metadata/init.py#L71-L77

adamchainz avatar Sep 15 '22 15:09 adamchainz

It should be but not

luuthang2011 avatar Sep 30 '22 07:09 luuthang2011

To make this work you need to edit your instance IMDSv2 hop limit...

aws ec2 modify-instance-metadata-options  --instance-id <instanceId> --http-put-response-hop-limit 3 --http-endpoint enabled

References:

IMDSv2*, then the default hop limit for getting metadata is set to 1. This hop limit will prevent Docker containers from accessing the metadata (assuming they're using a Docker network, not the host network).

source: Fetching AWS instance metadata from within Docker container?

kecsi-san avatar Dec 05 '22 18:12 kecsi-san

Great thanks @zoltan-kecskemethy-epam . Perhaps we could add a paragraph to the README.

adamchainz avatar Dec 05 '22 19:12 adamchainz