-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Append hosts to dependency container's /etc/hosts file #2518
Append hosts to dependency container's /etc/hosts file #2518
Conversation
c.state.BindMounts["/etc/resolv.conf"] = resolvPath | ||
} | ||
|
||
// check if dependency container has an /etc/hosts file | ||
hostsPath, exists := bindMounts["/etc/hosts"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've a defaultHostsFile defined now, could you use it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@TomSweeneyRedHat I wasn't sure if there should be a distinction of the map access in bind mounts (which happens quite a bit), and the access of the physical file /etc/hosts on the host system. If you think the former should be added, I'd also like to do the same with resolv.conf
libpod/container_internal_linux.go
Outdated
// If this file didn't exist before, save it in the depCtr's bind mount | ||
// so it isn't overwritten in the future | ||
if !exists { | ||
depCtr.state.BindMounts["/etc/hosts"] = hostsPath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto defaultHostFile
libpod/container_internal_linux.go
Outdated
hostsPath = defaultHostFile | ||
} | ||
// only go through all of this if we want to add a hosts file | ||
if len(hostsPath) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll let others way in. I'm muddling if we should remove the checks except " if !exists {" on line 712 or not? I think if a container doesn't have a hosts file we'd want to create it regardless? @mheon thoughts?
libpod/container_internal_linux.go
Outdated
// so it isn't overwritten in the future | ||
if !exists { | ||
depCtr.state.BindMounts["/etc/hosts"] = hostsPath | ||
depCtr.save() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should catch this error and log it, if nothing else
libpod/container_internal_linux.go
Outdated
// generate a hosts file for the dependency container, | ||
// based on either its old hosts file, or the default, | ||
// and add the relevant information from the new container (hosts and IP) | ||
hostsPath, err = depCtr.generateHosts(hostsPath, c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dunno if I like this... We won't pick this up until a restart, so it's not really shared.
Do we need to force sharing of /etc/hosts in this case, or is it sufficient to create it just for this container? We override resolv.conf for custom DNS settings when sharing network namespaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would other containers that are added to the namespace see it if a container they don't depend on (because they are laterally equal in the dependency tree)?
My other question is: where besides /etc/host creation is the BindMount() map needed? If a dependency container was started up and had an empty /etc/hosts, but needed it for whatever process that was running (that shouldn't be restarted to see these changes), wouldn't that process see the changes when the new container appended to the depCtr's /etc/hosts file? I guess the question is: the state of a process that runs will be out of sync, but only on the libpod end and not from the perspective of namespace management, which I think would work, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use the map to determine what bind mounts to add when creating the container spec. If we add to it after container creation time, it will never be picked up before a restart. Actually, now that I think about it, we force a regeneration of the bind mounts on each restart, so we'll never pick up this change - we'll overwrite it on restart.
Containers in the same Network Namespace are supposed to share the same /etc/resolv.conf and /etc/hosts file. These files either need to be created when the pod is created or the first container is added to a pod. Then each container that gets added to the pod needs to share the pods (initial containers) network and thus its resolv.conf and hosts file. Currently podman run -t --net=container:UUID Bottom line if there are 10 containers in a POD their is ONE resolv.conf and ONE hosts file bind mounted into each container. |
The issue is that we don't always create I think the solution is to force an unconditional creation/bind mount of |
I think that is fine. Does Docker commit changes to /etc/hosts? I would figure that is usually a mistake to commit them. |
/etc/hosts was unconditionally created. This PR now errors out if for some reason it wasn't but the dependency container is one for netNS. @rhatdan containers in the netNS did share the hosts file, the problem was --add-host didn't write anything to the dependency containers hosts, just ignored the flag. This PR now appends the contents of a new container using the --add-host flag, which fixes the issue. |
Also @mheon and I talked about the restart problem (a dependency container won't retain the hosts a new container adds to it after restarting), and it was decided there wasn't anything to do about it. Not really sure how to document this... |
@haircommander Lets talk about this tomorrow. |
bot, retest this please |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: haircommander, mheon The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Before, any container with a netNS dependency simply used its dependency container's hosts file, and didn't abide its configuration (mainly --add-host). Fix this by always appending to the dependency container's hosts file, creating one if necessary. Signed-off-by: Peter Hunt <pehunt@redhat.com>
/lgtm |
it seems to break the use case of:
|
Confirmed, looking at it |
I actually got it @mheon |
I know what's wrong here |
Alright I think I know what's going on here... Amazed it isn't happening for resolv too. |
it's from assuming we had an /etc/hosts file I think |
Before, any container with a netNS dependency simply used its dependency container's hosts file, and didn't abide its configuration (mainly --add-host). Fix this by always appending to the dependency container's hosts file, creating one if necessary.
fixes: #2504
Note: there will be a different PR for a similar action with resolv.conf, but considering resolv.conf is more complex, and this fixes the issue, I decided to file this first.