Skip to content

libnet: Endpoint: remove isAnonymous & myAliases#46853

Merged
thaJeztah merged 10 commits intomoby:masterfrom
akerouanton:libnet-ep-dns-names
Dec 20, 2023
Merged

libnet: Endpoint: remove isAnonymous & myAliases#46853
thaJeztah merged 10 commits intomoby:masterfrom
akerouanton:libnet-ep-dns-names

Conversation

@akerouanton
Copy link
Member

- What I did

The Endpoint struct was containing two confusing fields:

  1. isAnonymous: was set on endpoints which name shouldn't be taken into account when inserting DNS records into libnetwork's Controller.svcRecords (and into the NetworkDB). However, in that case the endpoint's aliases would still be used to create DNS records; thus, making those "anonymous endpoints" not so anonymous.
  2. myAliases: there's also an aliases field in the Endpoint struct. myAliases was storing extra DNS names for the endpoint, while aliases stores extra DNS names for other endpoints (but those extra DNS names are only accessible for the endpoint storing them -- yeah, it's confusing too).

To make it worse, the code that built the list of DNS names for a given endpoint was split in two:

  1. updateNetworkConfig (in the daemon pkg) was adding the endpoint short ID and hostname to the list of aliases ;
  2. In libnetwork, to handle "anonymous" endpoints as described above.

This PR replaces both fields with a new DNSNames containing all (non-fully qualified) DNS names for a given endpoint. It's now built by the daemon during updateNetworkConfig and reimplements the same logic for aliases as before (a test has been added to make sure of that). An "anonymous" endpoint is now an endpoint with no DNSNames.

This new field is also stored in the "operational data" (ie. state) of the EndpointSettings struct exposed by the API via GET /containers/{name:.*}/json, making it easier for end-users and scripts to know every DNS names a container has on a specific network.

- How to verify it

docker run --network testnet with a variety of:

  • --name ;
  • --hostname ;
  • --network-alias ;

- A picture of a cute animal (not mandatory but encouraged)

@akerouanton akerouanton self-assigned this Nov 27, 2023
@akerouanton akerouanton force-pushed the libnet-ep-dns-names branch 3 times, most recently from b2941c6 to ff4e67e Compare November 27, 2023 16:32
Copy link
Contributor

@robmry robmry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can the anonymous and myAliases fields be removed from the endpoint KVObjects without migration code? Wouldn't DNS resolution be subtly broken on containers carried across a daemon upgrade?

@akerouanton
Copy link
Member Author

akerouanton commented Nov 28, 2023

How can the anonymous and myAliases fields be removed from the endpoint KVObjects without migration code? Wouldn't DNS resolution be subtly broken on containers carried across a daemon upgrade?

Yeah, right. I overlooked this part. I added a commit to manage this case (see de2303b). However, I now realize the field EndpointSettings.DNSNames should be set on restore too, I'll fix that. I also resolved the other comments btw.

Some integration tests are broken as they expect the container short ID to be in EndpointSettings.Aliases. I think it's not a backward-incompatible change but what's your opinion @thaJeztah @corhere? At least, I should update version-history.md to make it clear.

Copy link
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some integration tests are broken as they expect the container short ID to be in EndpointSettings.Aliases. I think it's not a backward-incompatible change but what's your opinion @thaJeztah @corhere?

It's an API configuration field and integration tests are explicitly testing for that behaviour. Someone's workflow is going to break. I don't think it's safe to change the semantics of EndpointSettings.Aliases on released API versions.

Comment on lines -67 to -69
epMap["anonymous"] = ep.anonymous
epMap["dnsNames"] = ep.dnsNames
epMap["disableResolution"] = ep.disableResolution
epMap["myAliases"] = ep.myAliases
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should keep populating anonymous and myAliases in the marshaled objects so users could downgrade. Though only live-restored containers would be affected given that it's the endpoint object. As we already document that live-restore is only supported across patch upgrades we have no obligation to support major-version downgrades.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we explicitly specify we don't support live-restore for major upgrades, I think we shouldn't care much about live-restore for major downgrades.

@thaJeztah
Copy link
Member

Interesting; why is this test failing on this PR? (I was just looking at that test failing on my containerd vendor update PR; if it's failing here as well, perhaps it's just an existing issue?)

[2023-11-28T11:34:02.328Z] === RUN   TestAuthZPluginAllowEventStream
[2023-11-28T11:34:03.268Z] 2023/11/28 11:34:03 http: panic serving 127.0.0.1:54638: runtime error: invalid memory address or nil pointer dereference
[2023-11-28T11:34:03.268Z] goroutine 133 [running]:
[2023-11-28T11:34:03.268Z] net/http.(*conn).serve.func1()
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:1868 +0xb0
[2023-11-28T11:34:03.268Z] panic({0xa717e0?, 0x1579960?})
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/runtime/panic.go:920 +0x26c
[2023-11-28T11:34:03.268Z] github.com/docker/docker/integration/plugin/authz.setupSuite.func3({0xd690a8, 0x40000952c0}, 0xffff741c7728?)
[2023-11-28T11:34:03.268Z] 	/go/src/github.com/docker/docker/integration/plugin/authz/main_test.go:159 +0x14c
[2023-11-28T11:34:03.268Z] net/http.HandlerFunc.ServeHTTP(0x4000319f00?, {0xd690a8?, 0x40000952c0?}, 0x402c78?)
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:2136 +0x38
[2023-11-28T11:34:03.268Z] net/http.(*ServeMux).ServeHTTP(0xd6f178?, {0xd690a8, 0x40000952c0}, 0x4000319f00)
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:2514 +0x144
[2023-11-28T11:34:03.268Z] github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP(0x40001c2300, {0xd67c98?, 0x400017eee0}, 0x4000319e00)
[2023-11-28T11:34:03.268Z] 	/go/src/github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go:213 +0xf40
[2023-11-28T11:34:03.268Z] net/http.serverHandler.ServeHTTP({0xd64828?}, {0xd67c98?, 0x400017eee0?}, 0x6?)
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:2938 +0xbc
[2023-11-28T11:34:03.268Z] net/http.(*conn).serve(0x40001b42d0, {0xd6f178, 0x40000afe00})
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:2009 +0x518
[2023-11-28T11:34:03.268Z] created by net/http.(*Server).Serve in goroutine 19
[2023-11-28T11:34:03.268Z] 	/usr/local/go/src/net/http/server.go:3086 +0x4cc
[2023-11-28T11:34:04.207Z] 2023/11/28 11:34:04 http: panic serving 127.0.0.1:54644: could not unmarshal json for /AuthZPlugin.AuthZRes: unexpected end of JSON input
[2023-11-28T11:34:04.207Z] goroutine 191 [running]:
[2023-11-28T11:34:04.207Z] net/http.(*conn).serve.func1()
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:1868 +0xb0
[2023-11-28T11:34:04.207Z] panic({0xa09180?, 0x40004efa30?})
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/runtime/panic.go:920 +0x26c
[2023-11-28T11:34:04.207Z] github.com/docker/docker/integration/plugin/authz.setupSuite.func3({0xd690a8, 0x4000095380}, 0xffffbb165b98?)
[2023-11-28T11:34:04.207Z] 	/go/src/github.com/docker/docker/integration/plugin/authz/main_test.go:149 +0x360
[2023-11-28T11:34:04.207Z] net/http.HandlerFunc.ServeHTTP(0x40002de100?, {0xd690a8?, 0x4000095380?}, 0x402c78?)
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:2136 +0x38
[2023-11-28T11:34:04.207Z] net/http.(*ServeMux).ServeHTTP(0xd6f178?, {0xd690a8, 0x4000095380}, 0x40002de100)
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:2514 +0x144
[2023-11-28T11:34:04.207Z] github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP(0x40001c2300, {0xd67c98?, 0x400017efc0}, 0x40002de000)
[2023-11-28T11:34:04.207Z] 	/go/src/github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go:213 +0xf40
[2023-11-28T11:34:04.207Z] net/http.serverHandler.ServeHTTP({0x4000298600?}, {0xd67c98?, 0x400017efc0?}, 0x6?)
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:2938 +0xbc
[2023-11-28T11:34:04.207Z] net/http.(*conn).serve(0x400071d8c0, {0xd6f178, 0x40000afe00})
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:2009 +0x518
[2023-11-28T11:34:04.207Z] created by net/http.(*Server).Serve in goroutine 19
[2023-11-28T11:34:04.207Z] 	/usr/local/go/src/net/http/server.go:3086 +0x4cc
[2023-11-28T11:34:06.115Z] 2023/11/28 11:34:06 http: panic serving 127.0.0.1:54656: could not unmarshal json for /AuthZPlugin.AuthZRes: unexpected end of JSON input
[2023-11-28T11:34:06.115Z] goroutine 73 [running]:
[2023-11-28T11:34:06.115Z] net/http.(*conn).serve.func1()
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:1868 +0xb0
[2023-11-28T11:34:06.115Z] panic({0xa09180?, 0x40004ee0b0?})
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/runtime/panic.go:920 +0x26c
[2023-11-28T11:34:06.115Z] github.com/docker/docker/integration/plugin/authz.setupSuite.func3({0xd690a8, 0x40001be420}, 0xffff743f7a10?)
[2023-11-28T11:34:06.115Z] 	/go/src/github.com/docker/docker/integration/plugin/authz/main_test.go:149 +0x360
[2023-11-28T11:34:06.115Z] net/http.HandlerFunc.ServeHTTP(0x400001c100?, {0xd690a8?, 0x40001be420?}, 0x402c78?)
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:2136 +0x38
[2023-11-28T11:34:06.115Z] net/http.(*ServeMux).ServeHTTP(0xd6f178?, {0xd690a8, 0x40001be420}, 0x400001c100)
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:2514 +0x144
[2023-11-28T11:34:06.115Z] github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP(0x40001c2300, {0xd67c98?, 0x40000f0000}, 0x400001c000)
[2023-11-28T11:34:06.115Z] 	/go/src/github.com/docker/docker/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go:213 +0xf40
[2023-11-28T11:34:06.115Z] net/http.serverHandler.ServeHTTP({0x4000298030?}, {0xd67c98?, 0x40000f0000?}, 0x6?)
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:2938 +0xbc
[2023-11-28T11:34:06.115Z] net/http.(*conn).serve(0x40001b4090, {0xd6f178, 0x40000afe00})
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:2009 +0x518
[2023-11-28T11:34:06.115Z] created by net/http.(*Server).Serve in goroutine 19
[2023-11-28T11:34:06.115Z] 	/usr/local/go/src/net/http/server.go:3086 +0x4cc

@akerouanton akerouanton force-pushed the libnet-ep-dns-names branch 3 times, most recently from bcd3a26 to 6949b0b Compare December 14, 2023 23:37
They just happen to exist on a network that doesn't support DNS-based
service discovery (ie. no embedded DNS servers are started for them).

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This new property is meant to replace myAliases and anonymous
properties.

The end goal is to get rid of both properties by letting the daemon
determine what (non fully qualified) DNS names should be associated to
them.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Instead of special-casing anonymous endpoints in libnetwork, let the
daemon specify what (non fully qualified) DNS names should be associated
to container's endpoints.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This new property will be empty if the daemon was upgraded with
live-restore enabled. To not break DNS resolutions for restored
containers, we need to populate dnsNames based on endpoint's myAliases &
anonymous properties.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Instead of special-casing anonymous endpoints, use the list of DNS names
associated to the endpoint.

`(*Endpoint).isAnonymous()` has no more uses, so let's delete it.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The `(*Endpoint).rename()` method is changed to only mutate `ep.name`
and let a new method `(*Endpoint).UpdateDNSNames()` handle DNS updates.

As a consequence, the rollback code that was part of
`(*Endpoint).rename()` is now removed, and DNS updates are now
rolled back by `ContainerRename`.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The semantics of an "anonymous" endpoint has always been weird: it was
set on endpoints which name shouldn't be taken into account when
inserting DNS records into libnetwork's `Controller.svcRecords` (and
into the NetworkDB). However, in that case the endpoint's aliases would
still be used to create DNS records; thus, making those "anonymous
endpoints" not so anonymous.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This property is now unused, let's get rid of it.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
@akerouanton
Copy link
Member Author

I investigated the broken docker-py test to discover that the Container.run() method of docker-py returns the container struct as it was after the Container.create() call, not after the container was actually started.

Because of that, the failing integration test test_run_with_networking_config expects only Aliases that were submitted during the ContainerCreate call. Before this change, the container short ID was included in the Aliases field at run-time. However, to provide backward-compatibility this change always includes it. This python test will have to be fixed to not make a strict equality check, but instead check that the expected Aliases are there -- and ignore the additionnal Aliases.

No more concept of "anonymous endpoints". The equivalent is now an
endpoint with no DNSNames set.

Some of the code removed by this commit was mutating user-supplied
endpoint's Aliases to add container's short ID to that list. In order to
preserve backward compatibility for the ContainerInspect endpoint, this
commit also takes care of adding that short ID (and the container
hostname) to `EndpointSettings.Aliases` before returning the response.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@thaJeztah thaJeztah merged commit 7bc56c5 into moby:master Dec 20, 2023
@akerouanton akerouanton deleted the libnet-ep-dns-names branch December 20, 2023 21:21
akerouanton added a commit to akerouanton/cli that referenced this pull request Dec 20, 2023
Related to moby/moby#46853

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
akerouanton added a commit to akerouanton/cli that referenced this pull request Dec 20, 2023
Related to moby/moby#46853

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
thaJeztah added a commit to akerouanton/cli that referenced this pull request Dec 20, 2023
Related to moby/moby#46853

Co-Authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants