73 Commits

Author SHA1 Message Date
Cory Snider
16ed51d864 libnetwork/networkdb: always shut down memberlist
Gracefully leaving the memberlist cluster is a best-effort operation.
Failing to successfully broadcast the leave message to a peer should not
prevent NetworkDB from cleaning up the memberlist instance on close. But
that was not the case in practice. Log the error returned from
(*memberlist.Memberlist).Leave instead of returning it and proceed with
shutting down irrespective of whether Leave() returns an error.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-05-30 13:56:47 -04:00
Cory Snider
c9b01e0c4c libn/networkdb: SetPrimaryKey() under a write lock
(*NetworkDB).SetPrimaryKey() acquires a read lock on the NetworkDB
instance. That seems sound on the surface as it is only reading from the
NetworkDB struct, not mutating it. However, concurrent calls to
(*memberlist.Keyring).UseKey() would get flagged by Go's race detector
due to some questionable locking in its implementation. Acquire an
exclusive lock in SetPrimaryKey so concurrent calls don't race each
other.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-05-14 19:45:14 -04:00
Cory Snider
e3f9edd348 libn/networkdb: advertise the configured bind port
The NetworkDB unit tests instantiate clusters which communicate over
loopback where every "node" listens on a distinct localhost port. The
tests make use of a NetworkDB configuration knob to set the port. When
the NetworkDB configuration's BindPort field is set to a nonzero value,
its memberlist instance is configured to bind to the specified port
number. However, the advertise port is left at the
memberlist.DefaultLANConfig() default value of 7946. Because of this,
nodes would be unable to contact any of the other nodes in the cluster
learned by gossip as the gossiped addresseses specify the wrong ports!
The flaky tests passed as often as they did thanks to the robustness of
the memberlist module: NetworkDB gossip and and memberlist node
liveness-probe pings to unreachable nodes can all be relayed through
the reachable nodes, the nodes on the bootstrap join list.

Make the NetworkDB unit tests less flaky by setting each node's
advertise port to the bind port.

The daemon is unaffected by this oversight as it unconditionally uses
the default listen port of 7946, which aligns with the advertise port.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-05-07 11:38:12 -04:00
Matthieu MOREL
be54c79d9c fix(QF1006): Lift if+break into loop condition
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-05-01 14:17:42 +02:00
Sebastiaan van Stijn
f831618e5b libnetwork/networkdb: fix vars that shadowed (govet)
also moved the variables closer to where they're used

    libnetwork/networkdb/cluster.go:414:4: shadow: declaration of "nid" shadows declaration at line 397 (govet)
                nid := params[0]
                ^
    libnetwork/networkdb/networkdb.go:514:4: shadow: declaration of "nid" shadows declaration at line 506 (govet)
                nid := params[0]
                ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-04-28 15:23:50 +02:00
Nathan Baulch
59eba0ae13 Fix typos
Signed-off-by: Nathan Baulch <nathan.baulch@gmail.com>
2024-09-06 21:53:09 +10:00
Sebastiaan van Stijn
2847c4b7fe libnetwork/networkdb: switch to go-immutable-radix v2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2024-07-26 23:11:53 +02:00
Sebastiaan van Stijn
cff4f20c44 migrate to github.com/containerd/log v0.1.0
The github.com/containerd/containerd/log package was moved to a separate
module, which will also be used by upcoming (patch) releases of containerd.

This patch moves our own uses of the package to use the new module.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-10-11 17:52:23 +02:00
Brian Goff
74da6a6363 Switch all logging to use containerd log pkg
This unifies our logging and allows us to propagate logging and trace
contexts together.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2023-06-24 00:23:44 +00:00
Cory Snider
3606d6a7cd Upgrade to golangci-lint v1.51.2
Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-02-22 14:17:30 -05:00
Cory Snider
d31fa84c7c libnet/networkdb: use atomics for stats counters
The per-network statistics counters are loaded and incremented without
any concurrency control. Use atomic integers to prevent data races
without having to add any synchronization.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-02-10 15:21:58 -05:00
Tibor Vass
eaa74497b8 libnetwork: use go-immutable-radix instead of radix
This commit allows to remove dependency on the mutable version armon/go-radix.

The go-immutable-radix package is better maintained.

It is likely that a bit more memory will be used when using the
immutable version, though discarded nodes are being reused in a pool.
These changes happen when networks are added/removed or nodes come and
go in a cluster, so we are still talking about a relatively low
frequency event.

The major changes compared to the old radix are when modifying (insert
or delete) a tree, and those are pretty self-contained: we replace the
entire immutable tree under a lock.

Signed-off-by: Tibor Vass <teabee89@gmail.com>
2022-11-30 17:03:46 -08:00
Sebastiaan van Stijn
cd381aea56 libnetwork: fix empty-lines (revive)
libnetwork/etchosts/etchosts_test.go:167:54: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/osl/route_linux.go:185:74: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/osl/sandbox_linux_test.go:323:36: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/bitseq/sequence.go:412:48: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/datastore/datastore_test.go:67:46: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/datastore/mock_store.go:34:60: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/iptables/firewalld.go:202:44: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/iptables/firewalld_test.go:76:36: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/iptables/iptables.go:256:67: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/iptables/iptables.go:303:128: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/networkdb/cluster.go:183:72: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/ipams/null/null_test.go:44:38: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/macvlan/macvlan_store.go:45:52: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/ipam/allocator_test.go:1058:39: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/bridge/port_mapping.go:88:111: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/bridge/link.go:26:90: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/bridge/setup_ipv6_test.go:17:34: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/bridge/setup_ip_tables.go:392:4: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/bridge/bridge.go:804:50: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/ov_serf.go:183:29: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/ov_utils.go:81:64: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/overlay/peerdb.go:172:67: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/peerdb.go:209:67: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/peerdb.go:344:89: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/peerdb.go:436:63: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/overlay.go:183:36: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/drivers/overlay/encryption.go:69:28: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/drivers/overlay/ov_network.go:563:81: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/default_gateway.go:32:43: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/errors_test.go:9:40: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/service_common.go:184:64: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/endpoint.go:161:55: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/store.go:320:33: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/store_linux_test.go:11:38: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/sandbox.go:571:36: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/service_common.go:317:246: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/endpoint.go:550:17: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/sandbox_dns_unix.go:213:106: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/controller.go:676:85: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/agent.go:876:60: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/resolver.go:324:69: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/network.go:1153:92: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/network.go:1955:67: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/network.go:2235:9: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/libnetwork_internal_test.go:336:26: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/resolver_test.go:76:35: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/libnetwork_test.go:303:38: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/libnetwork_test.go:985:46: empty-lines: extra empty line at the end of a block (revive)
    libnetwork/ipam/allocator_test.go:1263:37: empty-lines: extra empty line at the start of a block (revive)
    libnetwork/errors_test.go:9:40: empty-lines: extra empty line at the end of a block (revive)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-26 19:21:58 +02:00
Sebastiaan van Stijn
561a010161 linting: suppress false positive for G404 (gosec)
The linter falsely detects this as using "math/rand":

    libnetwork/networkdb/cluster.go:721:14: G404: Use of weak random number generator (math/rand instead of crypto/rand) (gosec)
       val, err := rand.Int(rand.Reader, big.NewInt(int64(n)))
                   ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-04 15:36:49 +02:00
Sebastiaan van Stijn
b9c8eca468 libnetwork/networkdb: remove some redundant fmt.Sprintf()'s
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-02-15 12:56:23 +01:00
frobnicaty
d78b883576 Fix grammar for "does not exist"
as opposed to "does not exists"

Signed-off-by: frobnicaty <92033765+frobnicaty@users.noreply.github.com>
2021-12-03 15:50:13 +00:00
Roman Volosatovs
d7a2635537 libnetwork: make rejoin intervals configurable
This allows the rejoin intervals to be chosen according to the context
within which the component is used, and, in particular, this allows
lower intervals to be used within TestNetworkDBIslands test.

Signed-off-by: Roman Volosatovs <roman.volosatovs@docker.com>
2021-07-12 19:25:49 +02:00
Brian Goff
116f200737 Fix gosec complaints in libnetwork
These were purposefully ignored before but this goes ahead and "fixes"
most of them.
Note that none of the things gosec flagged are problematic, just
quieting the linter here.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2021-06-25 18:02:03 +02:00
Brian Goff
4b981436fe Fixup libnetwork lint errors
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2021-06-01 23:48:32 +00:00
Flavio Crisciani
2b1e45c682 Merge pull request #2238 from talex5/networkdb-docs
Add NetworkDB docs
2019-03-14 16:05:31 -07:00
Flavio Crisciani
151f42aeaa Fix possible nil pointer exception
It is possible that the node is not yet present in
the node list map. In this case just print a warning
and return. The next iteration would be fine

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2019-01-22 17:07:15 -08:00
Thomas Leonard
05c05ea5e9 Add NetworkDB docs
This is based on reading the code in the `networkdb` directory.

Signed-off-by: Thomas Leonard <thomas.leonard@docker.com>
2018-08-08 13:35:11 +01:00
Josh Soref
a06f1b2c4e Spelling fixes
* addresses
* assigned
* at least
* attachments
* auxiliary
* available
* cleanup
* communicate
* communications
* configuration
* connection
* connectivity
* destination
* encountered
* endpoint
* example
* existing
* expansion
* expected
* external
* forwarded
* gateway
* implementations
* implemented
* initialize
* internally
* loses
* message
* network
* occurred
* operational
* origin
* overlapping
* reaper
* redirector
* release
* representation
* resolver
* retrieve
* returns
* sanbdox
* sequence
* succesful
* synchronizing
* update
* validates

Signed-off-by: Josh Soref <jsoref@gmail.com>
2018-07-12 12:54:44 -07:00
Flavio Crisciani
b0a0059237 Merge pull request #2216 from fcrisciani/netdb-qlen-issue
NetworkDB qlen optimization
2018-07-05 15:02:58 -07:00
Chris Telfer
06922d2d81 Use fmt precision to limit string length
The previous code used string slices to limit the length of certain
fields like endpoint or sandbox IDs.  This assumes that these strings
are at least as long as the slice length.  Unfortunately, some sandbox
IDs can be smaller than 7 characters.   This fix addresses this issue
by systematically converting format string calls that were taking
fixed-slice arguments to use a precision specifier in the string format
itself.  From the golang fmt package documentation:

    For strings, byte slices and byte arrays, however, precision limits
    the length of the input to be formatted (not the size of the output),
    truncating if necessary. Normally it is measured in runes, but for
    these types when formatted with the %x or %X format it is measured
    in bytes.

This nicely fits the desired behavior: it will limit the number of
runes considered for string interpolation to the precision value.

Signed-off-by: Chris Telfer <ctelfer@docker.com>
2018-07-05 17:44:04 -04:00
Flavio Crisciani
55e4cc7262 Optimize networkDB queue
Added some optimizations to reduce the messages in the queue:
1) on join network the node execute a tcp sync with all the nodes that
it is aware part of the specific network. During this time before the
node was redistributing all the entries. This meant that if the network
had 10K entries the queue of the joining node will jump to 10K. The fix
adds a flag on the network that would avoid to insert any entry in the
queue till the sync happens. Note that right now the flag is set in
a best effort way, there is no real check if at least one of the nodes
succeed.
2) limit the number of messages to redistribute coming from a TCP sync.
Introduced a threshold that limit the number of messages that are
propagated, this will disable this optimization in case of heavy load.

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2018-07-02 16:59:45 -07:00
Flavio Crisciani
500d9f4515 Adjust corner case for reconnect logic
Previous logic was not accounting that each node is
in the node list so the bootstrap nodes won't retry
to reconnect because they will always find themselves
in the node map
Added test that validate the gossip island condition

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2018-06-21 18:04:55 -07:00
Dani Louca
96472cdaea Adding a recovery mechanism for a split gossip cluster
Signed-off-by: Dani Louca <dani.louca@docker.com>
2018-04-23 14:18:46 -04:00
Flavio Crisciani
f0fcb0bbe6 Fixed race on quick node fail/join
The previous logic was not properly handling the case of a node
that was failing and oining back in short period of time.
The issue was in the handling of the network messages.
When a node joins it sync with other nodes, these are passing
the whole list of nodes that at best of their knowledge are part
of a network. At this point if the node receives that node A is part
of the network it saves it before having received the notification
that node A is actually alive (coming from memberlist).
If node A failed the source node will receive the notification
while the new joined node won't because memberlist never advertise
node A as available. In this case the new node will never purge
node A from its state but also worse, will accept any table notification
where node A is the owner and so will end up in a out of sync state
with the rest of the cluster.

This commit contains also some code cleanup around the area of node
management

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-11-27 14:38:06 -08:00
Flavio Crisciani
7fbaf6de2c Add test to confirm garbage collection
- Create a test to verify that a node that joins
  in an async way is not going to extend the life
  of a already deleted object

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-10-23 09:58:57 +02:00
Flavio Crisciani
8c31217a44 NetworkDB create NodeID for cluster nodes
Separate the hostname from the node identifier. All the messages
that are exchanged on the network are containing a nodeName field
that today was hostname-uniqueid. Now being encoded as strings in
the protobuf without any length restriction they plays a role
on the effieciency of protocol itself. If the hostname is very long
the overhead will increase and will degradate the performance of
the database itself that each single cycle by default allows 1400
bytes payload

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-09-26 10:48:04 -07:00
Flavio Crisciani
a4e64d05c1 Avoid alignment of reapNetwork and tableEntries
Make sure that the network is garbage collected after
the entries. Entries to be deleted requires that the network
is present.

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-09-22 10:57:47 -07:00
Flavio Crisciani
053a534ab1 Changed ReapTable logic
- Changed the loop per network. Previous implementation was taking a
  ReadLock to update the reapTime but now with the residualReapTime
  also the bulkSync is using the same ReadLock creating possible
  issues in concurrent read and update of the value.
  The new logic fetches the list of networks and proceed to the
  cleanup network by network locking the database and releasing it
  after each network. This should ensure a fair locking avoiding
  to keep the database blocked for too much time.

  Note: The ticker does not guarantee that the reap logic runs
  precisely every reapTimePeriod, actually documentation says that
  if the routine is too long will skip ticks. In case of slowdown
  of the process itself it is possible that the lifetime of the
  deleted entries increases, it still should not be a huge problem
  because now the residual reaptime is propagated among all the nodes
  a slower node will let the deleted entry being repropagate multiple
  times but the state will still remain consistent.

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-09-21 09:37:47 -07:00
Flavio Crisciani
2d2a2bc568 Fix reapTime logic in NetworkDB
- Added remainingReapTime field in the table event.
  Wihtout it a node that did not have a state for the element
  was marking the element for deletion setting the max reapTime.
  This was creating the possibility to keep the entry being resync
  between nodes forever avoding the purpose of the reap time
  itself.

- On broadcast of the table event the node owner was rewritten
  with the local node name, this was not correct because the owner
  should continue to remain the original one of the message

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-09-21 09:37:37 -07:00
Derek McGowan
710e0664c4 Update logrus to v1.0.1
Fix case sensitivity issue
Update docker and runc vendors

Signed-off-by: Derek McGowan <derek@mcgstyle.net>
2017-08-07 11:20:47 -07:00
Flavio Crisciani
d6440c9139 optimize the rebroadcast for failure case
Before when a node was failing, all the nodes would bump the lamport time of all their
entries. This means that if a node flap, there will be a storm of update of all the entries.
This commit on the base of the previous logic guarantees that only the node that joins back
will readvertise its own entries, the other nodes won't need to advertise again.

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-08-01 14:08:54 -07:00
Flavio Crisciani
60b5add4af NetworkDB allow setting PacketSize
- Introduce the possibility to specify the max buffer length
  in network DB. This will allow to use the whole MTU limit of
  the interface

- Add queue stats per network, it can be handy to identify the
  node's throughput per network and identify unbalance between
  nodes that can point to an MTU missconfiguration

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-07-26 13:44:33 -07:00
Flavio Crisciani
051a0d5ce9 NetworkDB incorrect number of entries in networkNodes
A rapid (within networkReapTime 30min) leave/join network
can corrupt the list of nodes per network with multiple copies
of the same nodes.
The fix makes sure that each node is present only once

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-07-18 16:57:49 -07:00
Santhosh Manohar
ca9a768d80 Handle single manager reload by having workers reconnect
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
2017-05-31 14:36:23 -07:00
Santhosh Manohar
06c3489bb8 retry once on a bulk sync failure
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
2017-05-11 21:13:18 -07:00
Flavio Crisciani
da9ac65ea6 Remove explicit set of memberlist protocol
Memberlist does a full validation of the protocol version (min, current, max)
amoung all the ndoes of the cluster.
The previous code was setting the protocol version to max version.
That made the upgrade incompatible.

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
2017-05-08 16:58:53 -07:00
Santhosh Manohar
102f9d230d Avoid nDB stale entries because of intermittent nw issues.
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
2017-04-19 14:01:28 -07:00
Aaron Lehmann
bb8b9a6040 networkdb: Properly format memberlist logs
Right now, items logged by memberlist end up as a complete log line
embedded inside another log line, like the following:

    Nov 22 16:34:16 hostname dockerd: time="2016-11-22T16:34:16.802103258-08:00" level=info msg="2016/11/22 16:34:16 [INFO] memberlist: Marking xyz-1d1ec2dfa053 as failed, suspect timeout reached\n"

This has two time and date stamps, and an escaped newline inside the
"msg" field of the outer log message.

To fix this, define a custom logger that only prints the message itself.
Capture this message in logWriter, strip off the log level (added
directly by memberlist), and route to the appropriate logrus method.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2016-12-01 19:08:07 -08:00
Alessandro Boch
fac86cf69a Add missing locks in agent and service code
Signed-off-by: Alessandro Boch <aboch@docker.com>
2016-11-29 13:58:06 -08:00
Santhosh Manohar
31dd4362a8 Merge pull request #1542 from allencloud/change-reapNode-interval
update reapNode interval
2016-11-08 11:14:23 -08:00
allencloud
0b4f68390d remove unused mConfig
Signed-off-by: allencloud <allen.sun@daocloud.io>
2016-11-08 18:18:55 +08:00
allencloud
99f84ff5a7 update reapNode interval
Signed-off-by: allencloud <allen.sun@daocloud.io>
2016-11-08 15:28:42 +08:00
Santhosh Manohar
e98b152bac Reap failed nodes after 24 hours
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
2016-10-20 11:24:04 -07:00
Santhosh Manohar
0a2537eea3 Use monotonic clock for reaping networkDB entries
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
2016-10-19 22:30:47 -07:00
Alexander Morozov
03088ace1b networkdb: fix race in access to nodes len
Signed-off-by: Alexander Morozov <lk4d4math@gmail.com>
2016-10-04 12:19:25 -07:00