Skip to content

envoy drain duration should adapt to pod spec #34855

Description

@kyessenov

There are four (!) settings controlling the sidecar termination duration:

  1. drainDuration is envoy's graceful drain duration (default 45s).
  2. parentShutdownDuration is envoy's parent shutdown delay (default 60s).
  3. terminationDrainDuration is pilot-agent's termination duration delay after SIGTERM (default 5s).
  4. terminationGracefulPeriodSeconds is pod's graceful termination delay after SIGTERM before SIGKILL (default 30s).

This is very confusing and is actually inconsistent since (1)-(3) are normally mesh-level and (4) is pod-level. (4) overrides (3), and (3) overrides (1), while (2) is not used. (3) is also too short to be meaningful since envoy's drain is passive.

The proposal is to use (4) as the main deadline since it's orchestrated by kubelet irrespective of mesh-level settings. In this world, there is just one graceful deadline value (4) that dictates how long envoy gracefully drains open connections before shutting down. That means envoy is not terminated abruptly without sending final telemetry, for example. The process would look like this:

  1. On SIGTERM, agent initiates inbound listener graceful drain using (4) as the deadline. GOAWAY and connection:close are sent on all inbound connections, no more inbound connections are accepted, container readiness fails, endpoint removed from the pools. The max drain deadline is set by (4), but envoy can be stopped before that once all outstanding requests/connections are finished (including outbound app-driven). It's probably good to have a fixed minimum delay because detecting if an app (peer container) has outstanding requests is difficult (alternatively, CNI can undo outbound iptables on termination).
  2. After (4) seconds, SIGKILL is issued if envoy does not stop before that.

cc @ramaraochavali @mandarjog

Activity

  1. kyessenov commented on Aug 24, 2021

    @kyessenov
    ContributorAuthor
  2. howardjohn commented on Aug 25, 2021

    @howardjohn
    Member

    We use --drain-strategy immediate which should somewhat help "envoy's drain is passive" if you weren't aware - doesn't work in all cases though.

    Overall I agree we should do this. A few concerns I think we will need to work out:

    • what we should do if users set terminationDrainDuration (or just have the old default of 5s)?
    • Will we hit any cases where we get stuck? For example, I have seen some users set terminationGracefulPeriodSeconds to extreme values (>10 minutes) - if there are cases where their pod would have shut down and now it doesn't we may run into issues

    The benefits largely outweigh the issues, but I we should see what we can do to address those

  3. kyessenov commented on Aug 25, 2021

    @kyessenov
    ContributorAuthor

    @howardjohn It's passive because Envoy does not signal clients pro-actively. On a long-living connection with few requests, clients simply don't receive any notification. For very long grace periods, we have to implement polling for open connections so that if app exits early, proxy does, too. If we do pursue this, I'd imagine flags (1)-(3) are no longer useful. 5s is a dangerously low value, more so for apps with very longs shutdowns.

  4. kyessenov commented on Aug 30, 2021

    @kyessenov
    ContributorAuthor

    One complication is that health checks (and some other endpoints) go through Envoy and those should not count as application connections during drain.

  5. kyessenov commented on Aug 30, 2021

    @kyessenov
    ContributorAuthor

    Tagging @hzxuzhonghu.

  6. ramaraochavali commented on Sep 7, 2021

    @ramaraochavali
    Contributor

    One complication is that health checks (and some other endpoints) go through Envoy and those should not count as application connections during drain.

    This is exactly the same reason why we can not completely depend on Envoy to provide draining connection count.

  7. kevin-lindsay-1 commented on Oct 8, 2021

    @kevin-lindsay-1
    Contributor

    I just ran into this issue; one of my services has a high maximum but low average request time, so it gracefully shuts itself down, but once it's actually exited the sidecar persists and waits around even though there's no active connections.

    Hopefully I see this in a release soon, because I'd really like to test it and have even faster resource freeing across our clusters.

  8. ramaraochavali commented on Oct 11, 2021

    @ramaraochavali
    Contributor

    @kevin-lindsay-1 #35059 has this implementation. You can set EXIT_ON_ZERO_ACTIVE_CONNECTIONS on Agent side and try it. Please let us know how it works

  9. kevin-lindsay-1 commented on Oct 11, 2021

    @kevin-lindsay-1
    Contributor

    @ramaraochavali I use helm to install istio, and can change the image tags. Are there image builds that I could try out?

  10. ramaraochavali commented on Oct 11, 2021

    @ramaraochavali
    Contributor
  11. kevin-lindsay-1 commented on Oct 11, 2021

    @kevin-lindsay-1
    Contributor

    @ramaraochavali I use dockerhub for my images; can you tell me what I'd need to change on the helm chart for istio-discovery to test that image, because I'm getting an error when trying to switch stuff to that hub/tag.

  12. ramaraochavali commented on Oct 12, 2021

    @ramaraochavali
    Contributor

    Sorry. I am not aware of that. May be @howardjohn knows about it

  13. howardjohn commented on Oct 12, 2021

    @howardjohn
    Member
  14. kevin-lindsay-1 commented on Oct 12, 2021

    @kevin-lindsay-1
    Contributor

    @howardjohn sorry, I understand the values to set, but I don't know what the actual hub and tag values would be, as this appears to be a google hub and tag, and the attempts I made all gave me errors.

    Not experienced with using google storage as a hub, to the point where I'm not even 100% that it's compatible as an implementation of a docker hub.

  15. howardjohn commented on Oct 12, 2021

    @howardjohn
    Member
  16. 44 remaining items

  17. ramaraochavali commented on Jun 5, 2022

    @ramaraochavali
    Contributor

    Sorry I have been busy with other stuff. PR for backport #39286 to 1.12

  18. added
    lifecycle/staleIndicates a PR or issue hasn't been manipulated by an Istio team member for a while
    on Sep 3, 2022
  19. istio-policy-bot commented on Sep 18, 2022

    @istio-policy-bot

    🚧 This issue or pull request has been closed due to not having had activity from an Istio team member since 2022-06-05. If you feel this issue or pull request deserves attention, please reopen the issue. Please see this wiki page for more information. Thank you for your contributions.

    Created by the issue and PR lifecycle manager.

  20. batchamalick commented on Nov 17, 2022

    @batchamalick

    Hi @ramaraochavali ,
    While testing the setting EXIT_ON_ZERO_ACTIVE_CONNECTIONS: 'true' ,I deliberately kept an active connection and killed the pod using kubectl delete ,the envoy logs says one active connection clearly but after the terminationGracefulPeriod the istio-proxy + app is killed with active connection, Should there be a doc to say that user needs to adjust the terminationGracefulPeriod if the app takes more time than default 30s.

  21. ramaraochavali commented on Nov 17, 2022

    @ramaraochavali
    Contributor

    Sure. We can update the docs

  22. ldemailly commented on Dec 9, 2022

    @ldemailly
    Member

    EXIT_ON_ZERO_ACTIVE_CONNECTIONS isn't mentioned in latest docs - has the default changed to true or it still exists in current istio as an option? and maybe related is there an uptodate doc on how to ensure the proxy doesn't die or breaks the network before the service ends, while at the same time stop new traffic from coming in asap?

  23. howardjohn commented on Dec 9, 2022

    @howardjohn
    Member

    Its there on https://preliminary.istio.io/latest/docs/reference/commands/pilot-agent/. This is an experimental feature so there is not more docs beyond the generated reference.

  24. jbilliau-rcd commented on Feb 3, 2023

    @jbilliau-rcd

    For future readers here, we implemented this on our Kafka app that would throw 5xx's whenever pods scaled down due to Envoy terminating before the app could finish its outstanding requests. Implemented at 3:25, looks to have fixed it!

    image

  25. jkleckner commented on Jan 26, 2024

    @jkleckner

    We have a service container that runs a background thread that needs to complete in-flight work and then exit.

    The terminationGracefulPeriodSeconds is used and the service container will exit earlier when the in-flight work completes.

    Waiting for istio connections to drain does not help with this situation since the background thread doesn't have an open connection. One suggestion I have seen floating around is to have the service container open an otherwise unneeded connection to the istio pod so that istio will wait until the service pod exits. But it feels kind of hacky. Suggestions?

  26. howardjohn commented on Jan 26, 2024

    @howardjohn
    Member

    https://istio.io/latest/blog/2023/native-sidecars/ is the perfect solution. Everything else is pretty rough. 1.29 is available on most platforms these days

  27. jkleckner commented on Jan 30, 2024

    @jkleckner

    Thanks! More motivation to get current on k8s. Is there a "least bad" approach in the meantime?

  28. howardjohn commented on Jan 30, 2024

    @howardjohn
    Member

    You can use terminationDrainDuration and set it high (works ok but is a static time), or use EXIT_ON_ZERO_ACTIVE_CONNECTIONS (experimental, doesn't work in some cases)

  29. jkleckner commented on Jan 31, 2024

    @jkleckner

    Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    lifecycle/automatically-closedIndicates a PR or issue that has been closed automatically.lifecycle/staleIndicates a PR or issue hasn't been manipulated by an Istio team member for a while

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions