-
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
Add host.containers.internal entry into container's etc/hosts #9972
Add host.containers.internal entry into container's etc/hosts #9972
Conversation
03073cf
to
7747541
Compare
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bblenard, 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 |
libpod/container_internal_linux.go
Outdated
@@ -1381,23 +1401,12 @@ func (c *Container) makeBindMounts() error { | |||
// other container. Unless we're not creating both of | |||
// them. | |||
var ( | |||
depCtr *Container | |||
nextCtr string | |||
depCtr *Container |
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.
Can drop this block and make depCtr, err = c.getRootNetNsDepCtr()
a :=
Will be a little cleaner
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.
@@ -1342,6 +1342,26 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti | |||
return c.save() | |||
} | |||
|
|||
// Retrieves a container's "root" net namespace container dependency. |
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.
Can you note that this returns nil if there is no dependency?
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 don't think this can be null unless there is an error, although I could be wrong. So would you like a note about it returning an nil on error? That being said I am adding some extra error handling in that function based on your comment, but it wont make sense if State.Container
interface function can return nil, nil
.
libpod/networking_linux.go
Outdated
@@ -36,7 +36,7 @@ import ( | |||
"golang.org/x/sys/unix" | |||
) | |||
|
|||
const ( | |||
var ( |
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.
Can you keep this block const
and then add a separate var
block below for the slirp4netns bit?
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 have changed this I just don't want to kick off another CICD run until I get the other things sorted out.
I'd like @AkihiroSuda or someone else familiar with slirp to verify the slirp address calculation bits. Overall looks good, few small comments. |
run_podman run --network slirp4netns:cidr=192.168.0.0/24,allow_host_loopback=true \ | ||
$IMAGE grep 192.168.0.2 /etc/hosts | ||
is "$output" "192.168.0.2 host.gateway.internal" "host.gateway.internal should be the cidr+2 address" | ||
} |
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'm not feeling this behavior is correct.
The CIDR+2 address isn't useful when slirp4netns is launched with --disable-host-loopback
.
And --disable-host-loopback
should not be removed, as exposing bare 127.0.0.1 to containers might result in container-breakout.
I suggest exposing the "real" host IP regardless to rootful/rootless.
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.
So what would be the alternative? Are you suggesting to derive all interface ip addresses not including lo
?
The issue (#5651) was to add behavior that reflects docker's host.docker.internal
.
I had a look through some of the docker code and as far as I can tell that is a configuration option given to the daemon so if a user asks for the host gateway address to be added to their container it is added based on that configuration docker-ce reference
So should podman have a similar configuration option?
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.
Are you suggesting to derive all interface ip addresses not including lo?
The first interface (eth0) would be fine
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'm not sure about this solution.
There can be so many different interfaces in so many different configurations that trying to derive an ip address from one of the interfaces seems unstable. I don't necessarily disagree that exposing the loopback interface to the container could result in a container breakout but this change doesn't give that access it simply puts a /etc/hosts
entry for that interface.
Like I said above. I think the only viable alternative is to make the interface a configurable option similar to dockerd's --host-gateway-ip
launch option.
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.
@AkihiroSuda bump in case you didn't see my last response
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.
Having an option SGTM
depCtr, _ = c.getRootNetNsDepCtr() | ||
} else if len(c.state.NetworkStatus) != 0 { | ||
depCtr = c | ||
} else { |
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.
This last block is not necessary. depCtr will be nil by default.
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'm not sure syntactically how to get rid of that block 😬
I added it because I wanted to ensure mutual exclusion between shared container network namespace configurations and containers with network namespaces created for them. Basically I didn't want the situation where
var depCtr *Container
if c.config.NetNsCtr != "" { // **TRUE**
// ignoring the error because there isn't anything to do
depCtr, _ = c.getRootNetNsDepCtr()
}
if len(c.state.NetworkStatus) != 0 { // **TRUE**
depCtr = c
}
But If that is not possible / something to worry about I can make them both if
's and remove the unnecessary block
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.
@rhatdan just in case you didn't see my response.
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.
Yes, that is fine.
libpod/container_internal_linux.go
Outdated
} else if c.config.NetMode.IsSlirp4netns() { | ||
hosts += fmt.Sprintf("%s host.gateway.internal\n", slirp4netnsGateway) | ||
} else { | ||
logrus.Debug("unexpected network configuration while determining host.gateway.internal address") |
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.
Is this unexpected, or would this just be the situation if I run a container with podman run --net=none ...
IE Is this worth logging?
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.
This would be the case for podman run --net=none
so I suppose it isn't that unexpected. Should I just quietly continue or change up the debug message?
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.
@rhatdan bump just in case you didn't see my response
@bblenard Thanks for working on this. |
@rhatdan can you merge this if it LGTY? I think there was one last "is this OK" type of question for you in the review comments on this one. |
Bikeshedding: For consistency with |
Yes lets go with |
7747541
to
724078f
Compare
I just pushed up some code and assuming the tests all pass there are just a few small things I want to make sure everyone is on the same page about:
|
The commit message ( host.gateway.internal ) seems to need to be updated |
971e347
to
f5e7b40
Compare
Fixed f5e7b40d66646b3e6517d989d8078110172808de |
LGTM |
@containers/podman-maintainers PTAL |
libpod/networking_slirp4netns.go
Outdated
return errors.Wrapf(err, "error calculating expected dns ip for slirp4netns") | ||
} | ||
// Save off calculated address into globals. I don't like this either | ||
slirp4netnsIP = expectedIP.String() |
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 don't think we should use globals, this will fail when used with the podman service.
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.
Okay, I'll look at moving away from the globals. I think when I initially wrote this those were constant values that I changed to variables so I didn't even think about if they should be globals. Thanks for catching that :)
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 think you can add a new field (maybe called slirp4netnsSubnet) to the container struct here
Line 97 in 663ea96
type Container struct { |
and add methods like GetSlirp4netnsIP, GetSlirp4netnsGateway and GetSlirp4netnsDNS which returns the correct ip calculated from the stored subnet.
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.
Fixed: c0335e77819e23be94bb55d883e18bdd6b742195
I made the helper functions generatl libpod functions that take subnets instead of Container functions that reference internal struct members because I didn't think it was a container specific thing. I also essentially reverted your changes here: f99b7a3 since I had a merge conflict and my changes covered what you did with that commit as far as I could tell.
@Luap99 I'll let you resolve these conversations if you think I properly addressed your comments.
libpod/networking_slirp4netns.go
Outdated
@@ -314,9 +314,53 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error { | |||
} | |||
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath) | |||
} | |||
|
|||
// Calculate Slirp addresses now that we are pretty sure the command executed |
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.
This block has to be above if havePortMapping...
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 fix that once I figure out how to move away from globals like you suggested above.
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.
Fixed: c0335e77819e23be94bb55d883e18bdd6b742195
f5e7b40
to
3ce696e
Compare
3ce696e
to
c0335e7
Compare
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.
Thanks this looks good. One small nit.
if err != nil { | ||
return nil, errors.Wrap(err, "failed to determine default slirp4netns DNS address") | ||
} | ||
|
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.
The block below here should also use GetSlirp4netnsDNS for consistency.
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.
Fixed: ef6027b2db9d7ebd4a294af002c08c0c93d0e5db
libpod/container_internal_linux.go
Outdated
hosts += fmt.Sprintf("# used by slirp4netns\n%s\t%s %s\n", slirp4netnsIP, c.Hostname(), c.config.Name) | ||
slirp4netnsIP, err := GetSlirp4netnsGateway(c.slirp4netnsSubnet) | ||
if err != nil { | ||
logrus.Error("failed to determine slirp4netnsIP: ", err.Error()) |
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.
This should be a warning not an error, If the user can not do anything about it, then it should just warn.
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.
Fixed: ef6027b2db9d7ebd4a294af002c08c0c93d0e5db
@edsantiago PTAL at the system tests. |
libpod/container_internal_linux.go
Outdated
nameservers = append([]string{slirp4netnsDNS}, nameservers...) | ||
slirp4netnsDNS, err := GetSlirp4netnsDNS(c.slirp4netnsSubnet) | ||
if err != nil { | ||
logrus.Error("failed to determine Slirp4netns DNS: ", err.Error()) |
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.
Warning not Error.
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.
Fixed: ef6027b2db9d7ebd4a294af002c08c0c93d0e5db
libpod/container_internal_linux.go
Outdated
} else if c.config.NetMode.IsSlirp4netns() { | ||
gatewayIP, err := GetSlirp4netnsGateway(c.slirp4netnsSubnet) | ||
if err != nil { | ||
logrus.Error("failed to determine gatewayIP: ", err.Error()) |
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.
Warning not error.
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.
Fixed: ef6027b2db9d7ebd4a294af002c08c0c93d0e5db
LGTM once Error->Warnin |
test/system/500-networking.bats
Outdated
@@ -162,6 +162,24 @@ load helpers | |||
done | |||
} | |||
|
|||
@test "podman run with slirp4ns assigns correct gateway address to host.containers.internal" { | |||
run_podman run --network slirp4netns:cidr=192.168.0.0/24 \ |
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.
Just curious: what problem does random_rfc1918_subnet()
have that prevents you from using it?
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 wasn't aware of that function. I added it to the tests I wrote 👍
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.
Thanks! One suggestion, though: I find string concatenation easier to read than stripping. Would you consider:
subnet=$(random_rfc1918_subnet)
... :cidr="$subnet.0/24"
.... grep "$subnet"
... nameserger "${subnet}.3"
That removes the need for all those complicated fragile %.*
, and makes life much easier for future maintainers.
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.
Sounds good. Fixed: c8dfcce
c0335e7
to
ef6027b
Compare
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.
LGTM
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bblenard, Luap99, 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 |
This change adds the entry `host.containers.internal` to the `/etc/hosts` file within a new containers filesystem. The ip address is determined by the containers networking configuration and points to the gateway address for the containers networking namespace. Closes containers#5651 Signed-off-by: Baron Lenardson <[email protected]>
ef6027b
to
c8dfcce
Compare
@@ -162,6 +162,27 @@ load helpers | |||
done | |||
} | |||
|
|||
@test "podman run with slirp4ns assigns correct gateway address to host.containers.internal" { | |||
CIDR="$(random_rfc1918_subnet)" |
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.
Much better, thank you, but I'm kind of uncomfortable now with the variable name: a CIDR is defined as a full subnet, slash, and mask. A future maintainer may find this a stumbling point, and waste time (e.g. on line 169) wondering how a CIDR can have .2
appended. This is about a 3-out-of-10 gripe, I'm not going to insist on you changing it, but I'd like to bring it to the attention of others in case someone else on the team has a strong opinion either way.
/lgtm |
Thanks @bblenard Nice work. |
Thanks! I've been enjoying working on podman :) |
This change adds the entry
host.containers.internal
to the/etc/hosts
file within a new containers filesystem. The ip address is determined by
the containers networking configuration and points to the gateway address
for the containers networking namespace.
Closes #5651
Signed-off-by: Baron Lenardson [email protected]