Skip to content
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

iptables: carry on and log on failure to set up transient rules #12006

Merged
merged 4 commits into from Jun 11, 2020

Conversation

qmonnet
Copy link
Member

@qmonnet qmonnet commented Jun 10, 2020

As reported in #11276, we have occasionally observed unexpected failures when trying to set up iptables transient rules (used to avoid dropping packets while reinitialising the daemon).

This set brings two changes:

  • Do not abort reinitialisation if transient rules set up fails (we risk dropping a few packets until Cilium's rules are up again, this is better than failing to restart the agent).

  • Log iptables messages on failures to flush or delete leftover transient rules, as we suspect this is the cause for the error messages observed, so we can understand what happens if the issue reoccurs.

Please refer to individual commit logs for details.

When Reinitialize()-ing the datapath, transient iptables rules are set
up to avoid dropping packets while Cilium's rules are not in place.

In rare occasions, a failure to add those rules has been observed (see
issue #11276), leading to an early exit from Reinitialize() and a
failure to set up the daemon.

But those transient rules are just used to lend a hand and keep packets
going for a very small window of time: it does not actually matter much
if we fail to install them, and it should not stop the reinitializing of
the daemon. Let's simply log a warning and carry on if we fail to add
those rules.

Signed-off-by: Quentin Monnet <quentin@isovalent.com>
@qmonnet qmonnet added area/daemon Impacts operation of the Cilium daemon. release-note/misc This PR makes changes that have no direct user impact. needs-backport/1.8 labels Jun 10, 2020
@qmonnet qmonnet requested review from borkmann, joestringer and a team June 10, 2020 14:16
@maintainer-s-little-helper maintainer-s-little-helper bot added this to In progress in 1.8.0 Jun 10, 2020
@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from master in 1.8.0 Jun 10, 2020
Copy link
Member

@pchaigno pchaigno left a comment

Choose a reason for hiding this comment

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

Would it be possible to see this bug in CI? Is it worth adding the new warning messages to badLogMessages so that we don't miss it if it happens in CI?

pkg/datapath/iptables/iptables.go Outdated Show resolved Hide resolved
@coveralls
Copy link

coveralls commented Jun 10, 2020

Coverage Status

Coverage decreased (-0.04%) to 37.035% when pulling f106702 on pr/qmonnet/log_ipt_transient_rules into 47f8d32 on master.

@qmonnet
Copy link
Member Author

qmonnet commented Jun 10, 2020

Would it be possible to see this bug in CI?

If filtering on debugTransientRules to avoid doing so for other rules when we pass quiet at false, this is probably doable. I'll look into it. Thanks!

We do the same thing for IPv4 and IPv6, with just the name of the
program changing. Then we do nearly the same thing for flushing and
deleting a chain. Let's refactor (no functional change).

Signed-off-by: Quentin Monnet <quentin@isovalent.com>
When Cilium reinitialises its daemon, transient iptables rules are set
up to avoid dropping packets while the regular rules are not in place.

On rare occasions, setting up those transient rules has been found to
fail, for an unknown reason (see issue #11276). The error message states
that the "Chain already exists", even though we try to flush and remove
any leftover from previous transient rules before adding the new ones.
It sounds likely that removing the leftovers is failing, but we were not
able to understand why, because we quieten the function to avoid
spurious warnings the first time we try to remove them (since none is
existing).

It would be helpful to get more information to understand what happens
in those rare occasions where setting up transient rules fails. Let's
find a way to get more logs, without making too much noise.

We cannot warn unconditionally in remove() since we want removal in the
normal case to remain quiet. What we can do is logging when the "quiet"
flag is not passed, _or_ when the error is different from the chain
being not found, i.e. when the error is different from the one we want
to silence on start up. This means matching on the error message
returned by ip(6)tables. It looks fragile, but at least this message has
not changed since 2009, so it should be relatively stable and pretty
much the same on all supported systems. Since remove() is used for
chains other than for transient rules too, we also match on chain name
to make sure we are dealing with transient rules if ignoring the "quiet"
flag.

This additional logging could be removed once we reproduce and fix the
issue.

Alternative approaches could be:

- Uncoupling the remove() function for transient rules and regular
  rules, to avoid matching on chain name (but it sounds worse).
- Logging on failure for all rules even when the "quiet" flag is passed,
  but on "info" level instead of "warning". This would still require a
  modified version of runProg(), with also a modified version of
  CombinedOutput() in package "exec". Here I chose to limit the number
  of logs and keep the changes local.
- Listing the chain first before trying to remove it, so we only try to
  remove if it exists, but this would likely add unnecessary complexity
  and latency.

Should help with (but does not solve): #11276
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
In an attempt to catch #11276 in CI, let's add any message related to a
failure to flush or delete the chain related to iptables transient rules
to the list of badLogMessages we want to catch.

We need to filter on the name of the chain for transient rules to avoid
false positives, which requires exporting that name.

We also need to modify the log message error, to avoid adding four
disting logs to the list (combinations for iptables/ip6tables,
flush/delete).

Signed-off-by: Quentin Monnet <quentin@isovalent.com>
@qmonnet qmonnet force-pushed the pr/qmonnet/log_ipt_transient_rules branch from 26e16d9 to f106702 Compare June 10, 2020 16:13
@qmonnet qmonnet requested a review from a team as a code owner June 10, 2020 16:13
@qmonnet qmonnet requested a review from pchaigno June 10, 2020 16:14
@qmonnet
Copy link
Member Author

qmonnet commented Jun 10, 2020

test-me-please

@maintainer-s-little-helper maintainer-s-little-helper bot added this to Needs backport from master in 1.7.5 Jun 11, 2020
@aanm aanm merged commit e78405a into master Jun 11, 2020
1.8.0 automation moved this from In progress to Merged Jun 11, 2020
@aanm aanm deleted the pr/qmonnet/log_ipt_transient_rules branch June 11, 2020 14:50
@aanm aanm mentioned this pull request Jun 11, 2020
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from master to Backport pending to v1.8 in 1.8.0 Jun 11, 2020
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Needs backport from master to Backport pending to v1.7 in 1.7.5 Jun 11, 2020
@maintainer-s-little-helper maintainer-s-little-helper bot moved this from Backport pending to v1.8 to Backport done to v1.8 in 1.8.0 Jun 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/daemon Impacts operation of the Cilium daemon. release-note/misc This PR makes changes that have no direct user impact.
Projects
No open projects
1.7.5
Backport pending to v1.7
1.8.0
  
Merged
1.8.0
Backport done to v1.8
Development

Successfully merging this pull request may close these issues.

None yet

7 participants