|
1 | 1 | A service that runs on an EC2 instance that proxies the EC2 instance metadata service
|
2 |
| -for docker containers. The proxy overrides metadata endpoints for individual docker |
| 2 | +for linux containers. The proxy overrides metadata endpoints for individual |
3 | 3 | containers.
|
4 | 4 |
|
| 5 | +The following container platforms are supported: |
| 6 | + |
| 7 | +* [docker](https://www.docker.com) |
| 8 | +* [flynn](https://flynn.io) |
| 9 | + |
5 | 10 | At this point, the only endpoint overridden is the security credentials. This allows
|
6 | 11 | for different containers to have different IAM permissions and not just use the permissions
|
7 | 12 | provided by the instance profile. However, this same technique could be used to override
|
8 | 13 | any other endpoints where appropriate.
|
9 | 14 |
|
10 |
| -# Build |
11 |
| - |
12 |
| -Requires: |
13 |
| - |
14 |
| -* golang 1.2+ |
15 |
| -* make |
| 15 | +The proxy works by mapping the metadata source request IP to the container using the container |
| 16 | +platform specific API. The container's metadata contains information about what IAM permissions |
| 17 | +to use. Therefore, the proxy does not work for containers that do not use the container |
| 18 | +network bridge (for example, containers using "host" networking). |
16 | 19 |
|
17 |
| -The dependencies are managed with git submodules. After cloning, make sure to initialize the submodules: |
18 |
| - |
19 |
| -```bash |
20 |
| -# Either initialize submodules when you clone the repo |
21 |
| -git clone --recursive [email protected]:dump247/docker-ec2-metadata.git |
22 |
| - |
23 |
| -# Or, if you have already cloned, initialize the submodules |
24 |
| -git submodule update --init --recursive |
25 |
| -``` |
| 20 | +# Setup |
26 | 21 |
|
27 |
| -Run `make` or `make build`. The resulting executable will be in `bin/`. |
| 22 | +## Host |
28 | 23 |
|
29 |
| -Run `make clean` to clear out any build artifacts. |
| 24 | +The host EC2 instance must have firewall settings that redirect any EC2 metadata connections |
| 25 | +from containers to the metadata proxy. The proxy will then process the request and |
| 26 | +may forward the request to the real metadata service. |
30 | 27 |
|
31 |
| -## RPM |
| 28 | +The instance profile of the host EC2 instance must also have permission to assume the IAM roles |
| 29 | +for the containers. |
32 | 30 |
|
33 |
| -Requires: |
| 31 | +See: |
34 | 32 |
|
35 |
| -* rpm-build |
| 33 | +* [Host Setup](docs/host-setup.md) |
36 | 34 |
|
37 |
| -1. Run `make` to create the executable |
38 |
| -2. Run `make rpm` to build the rpm |
| 35 | +## Containers |
39 | 36 |
|
40 |
| -The steps can all be performed at once with `make build rpm` or `make clean build rpm`. |
| 37 | +Containers do not require any changes or modifications to utilize the metadata proxy. By |
| 38 | +default, they will receive the default permissions configured by the proxy. Alternatively, |
| 39 | +a container can be configured to use a separate IAM role or provide an IAM policy. |
41 | 40 |
|
42 |
| -# Setup |
| 41 | +See: |
43 | 42 |
|
44 |
| -What is needed is an EC2 instance with assume role permissions and one or more roles defined |
45 |
| -that it can assume. The roles will be used by the containers to acquire their own permissions. |
46 |
| - |
47 |
| -## Permissions |
48 |
| - |
49 |
| -The EC2 instance must have permission to assume the roles required by the docker containers. |
50 |
| - |
51 |
| -Note that assuming a role is two way: the permission to assume roles has to be granted to the |
52 |
| -instance profile and the role has to allow the instance profile to assume it. |
53 |
| - |
54 |
| -There must be at least one role to use as the default role if the container has not specified |
55 |
| -one. The default role can have empty permissions (zero access) or some set of standard |
56 |
| -permissions. |
57 |
| - |
58 |
| -Example CloudFormation: |
59 |
| - |
60 |
| -* _DockerContainerRole1_ is the set of permissions for a docker container |
61 |
| -* _InstanceRole_ is the role used by the EC2 instance profile and needs permission to assume _DockerContainerRole1_ |
62 |
| - |
63 |
| -```json |
64 |
| -{ |
65 |
| - "AWSTemplateFormatVersion": "2010-09-09", |
66 |
| - "Resources": { |
67 |
| - "DockerContainerRole1": { |
68 |
| - "Type": "AWS::IAM::Role", |
69 |
| - "Properties": { |
70 |
| - "AssumeRolePolicyDocument": { |
71 |
| - "Statement": [ |
72 |
| - { |
73 |
| - "Effect": "Allow", |
74 |
| - "Principal": { |
75 |
| - "AWS": [ {"Fn::GetAtt" : ["InstanceRole", "Arn"]} ] |
76 |
| - }, |
77 |
| - "Action": [ "sts:AssumeRole" ] |
78 |
| - } |
79 |
| - ] |
80 |
| - }, |
81 |
| - "Path": "/docker/", |
82 |
| - "Policies": [] |
83 |
| - } |
84 |
| - }, |
85 |
| - |
86 |
| - "InstanceRole": { |
87 |
| - "Type": "AWS::IAM::Role", |
88 |
| - "Properties": { |
89 |
| - "AssumeRolePolicyDocument": { |
90 |
| - "Statement": [ |
91 |
| - { |
92 |
| - "Effect": "Allow", |
93 |
| - "Principal": { |
94 |
| - "Service": [ "ec2.amazonaws.com" ] |
95 |
| - }, |
96 |
| - "Action": [ "sts:AssumeRole" ] |
97 |
| - } |
98 |
| - ] |
99 |
| - }, |
100 |
| - "Path": "/", |
101 |
| - "Policies": [ |
102 |
| - { |
103 |
| - "PolicyName": "AssumeRoles", |
104 |
| - "PolicyDocument": { |
105 |
| - "Statement": [ |
106 |
| - { |
107 |
| - "Effect": "Allow", |
108 |
| - "Resource": {"Fn::Join": ["", ["arn:aws:iam::", {"Ref": "AWS::AccountId"}, ":role/docker/*"]]}, |
109 |
| - "Action": [ "sts:AssumeRole" ] |
110 |
| - } |
111 |
| - ] |
112 |
| - } |
113 |
| - } |
114 |
| - ] |
115 |
| - } |
116 |
| - }, |
117 |
| - |
118 |
| - "InstanceProfile": { |
119 |
| - "Type": "AWS::IAM::InstanceProfile", |
120 |
| - "Properties": { |
121 |
| - "Path": "/", |
122 |
| - "Roles": [{"Ref": "InstanceRole"}] |
123 |
| - } |
124 |
| - } |
125 |
| - } |
126 |
| -} |
127 |
| -``` |
128 |
| - |
129 |
| -## Instance Setup |
130 |
| - |
131 |
| -Install docker and run with the standard unix domain socket (_/var/run/docker.sock_). |
132 |
| - |
133 |
| -Setup a rule to route all metadata service traffic from the containers |
134 |
| -to the proxy service. By default, the proxy runs on _0.0.0.0:18000_, but this can |
135 |
| -be overridden. Be careful that you do not expose the service outside the EC2 instance! |
136 |
| - |
137 |
| -This script will setup the routing rules. You may need to adjust if you make changes |
138 |
| -to how docker sets up its networking. If you are an iptables ninja and can improve this, |
139 |
| -please submit a ticket or a pull request! |
140 |
| - |
141 |
| -```bash |
142 |
| -# Get the host IP address. You can use a different mechanism if you wish. |
143 |
| -# Note that IP can not be 127.0.0.1 because DNAT for loopback is not possible. |
144 |
| -PROXY_IP=$(ifconfig eth0 | grep -Eo "inet addr:[0-9.]+" | grep -Eo "[0-9.]+") |
145 |
| - |
146 |
| -# Port that the proxy service runs on. Default is 18000. |
147 |
| -PROXY_PORT=18000 |
148 |
| - |
149 |
| -# Drop any traffic to the proxy service that is NOT coming from docker containers |
150 |
| -iptables \ |
151 |
| - -I INPUT \ |
152 |
| - -p tcp \ |
153 |
| - --dport ${PROXY_PORT} \ |
154 |
| - ! -i docker0 \ |
155 |
| - -j DROP |
156 |
| - |
157 |
| -# Redirect any requests from docker containers to the proxy service |
158 |
| -iptables \ |
159 |
| - -t nat \ |
160 |
| - -I PREROUTING \ |
161 |
| - -p tcp \ |
162 |
| - -d 169.254.169.254 --dport 80 \ |
163 |
| - -j DNAT \ |
164 |
| - --to-destination ${PROXY_IP}:${PROXY_PORT} \ |
165 |
| - -i docker0 |
166 |
| -``` |
167 |
| - |
168 |
| -## Run the Service |
169 |
| - |
170 |
| -The proxy service will need to run as root or as a user in the _docker_ group. |
171 |
| - |
172 |
| -# Container Role |
173 |
| - |
174 |
| -If the container does not specify a role, the default role is used. A container can specify |
175 |
| -a specific role to use by setting the `IAM_ROLE` environment variable. |
176 |
| - |
177 |
| -Example: `IAM_ROLE=arn:aws:iam::123456789012:role/CONTAINER_ROLE_NAME` |
178 |
| - |
179 |
| -Note that the host machine’s instance profile must have permission to assume the given role. |
180 |
| -If not, the container will receive an error when requesting the credentials. |
| 43 | +* [Docker Container Setup](docs/docker-container-setup.md) |
| 44 | +* [Flynn Container Setup](docs/flynn-container-setup.md) |
181 | 45 |
|
182 | 46 | # License
|
183 | 47 |
|
|
0 commit comments