@@ -507,7 +507,10 @@ impl ClientConnectionHandler {
507
507
}
508
508
}
509
509
510
- /// Initializes the agent's [`State`], channels, threads, and runs [`ClientConnectionHandler`]s.
510
+ /// Real mirrord-agent routine.
511
+ ///
512
+ /// Obtains the PID of the target container (if there is any),
513
+ /// starts background tasks and listens for client connections.
511
514
#[ tracing:: instrument( level = Level :: TRACE , ret, err) ]
512
515
async fn start_agent ( args : Args ) -> AgentResult < ( ) > {
513
516
trace ! ( "start_agent -> Starting agent with args: {args:?}" ) ;
@@ -792,6 +795,10 @@ async fn clear_iptable_chain() -> Result<(), IPTablesError> {
792
795
Ok ( ( ) )
793
796
}
794
797
798
+ /// Runs the current binary as a child process,
799
+ /// using the exact same command line.
800
+ ///
801
+ /// When this future is aborted before completion, the child process is automatically killed.
795
802
async fn run_child_agent ( ) -> AgentResult < ( ) > {
796
803
let command_args = std:: env:: args ( ) . collect :: < Vec < _ > > ( ) ;
797
804
let ( command, args) = command_args
@@ -811,10 +818,12 @@ async fn run_child_agent() -> AgentResult<()> {
811
818
}
812
819
}
813
820
814
- /// Sets iptable chains' names in env (e.g. [`IPTABLE_PREROUTING_ENV`]) and spawns the main agent
821
+ /// Targeted agent's parent process.
822
+ ///
823
+ /// Sets iptable chains' names in env (e.g. [`IPTABLE_PREROUTING_ENV`]) and spawns the real agent
815
824
/// routine in the child process. When the child process exits, cleans the iptables.
816
825
///
817
- /// Captures SIGTERM signals sent by Kubernetes when the pod is gracefully deleted.
826
+ /// Captures SIGTERM signals sent by Kubernetes when the pod is being gracefully deleted.
818
827
/// When a signal is captured, the child process is killed and the iptables are cleaned.
819
828
async fn start_iptable_guard ( args : Args ) -> AgentResult < ( ) > {
820
829
debug ! ( "start_iptable_guard -> Initializing iptable-guard." ) ;
@@ -853,17 +862,32 @@ async fn start_iptable_guard(args: Args) -> AgentResult<()> {
853
862
result
854
863
}
855
864
856
- /// The agent is somewhat started twice, first with [`start_iptable_guard`], and then the
857
- /// proper agent with [`start_agent`].
865
+ /// mirrord-agent entrypoint.
866
+ ///
867
+ /// Installs a default [`CryptoProvider`](rustls::crypto::CryptoProvider) and initializes tracing.
868
+ ///
869
+ /// # Flow
870
+ ///
871
+ /// If the agent is targetless, it goes straight to spawning background tasks and listening for
872
+ /// client connections.
873
+ ///
874
+ /// If the agent has a target, the flow is a bit different.
875
+ /// This is because we might need to redirect incoming traffic.
858
876
///
859
- /// ## Things to keep in mind due to the double initialization
877
+ /// First, the agent generates randomized names for our iptables chains
878
+ /// and puts them into some environment variables (e.g [`IPTABLE_PREROUTING_ENV`]).
879
+ /// Then, it spawns a child process with the exact same command line,
880
+ /// and waits for a SIGTERM signal. When the signal is received or the child process fails,
881
+ /// the agent cleans the iptables (based on the previously set environment variables) before
882
+ /// exiting.
860
883
///
861
- /// Since the _second_ agent gets spawned as a child of the _first_, they share resources,
862
- /// like the `namespace`, which means:
884
+ /// The child process is the real agent, which spawns background tasks and listens for client
885
+ /// connections. The child process knowns is the real agent, because it has the environment
886
+ /// variables set.
863
887
///
864
- /// 1. If you try to `bind` a socket to some address before [`start_agent`], it'll actually be bound
865
- /// **twice**, which incurs an error (address already in use). You could get around this by
866
- /// `bind`ing on `0.0.0.0:0`, but this is most likely **not** what you want .
888
+ /// This weird flow is a safety measure - should the real agent OOM (which means instant process
889
+ /// termination) or be killed with a signal, the parent will a chance to clean iptables. If we leave
890
+ /// the iptables dirty, the whole target pod is broken, probably forever .
867
891
pub async fn main ( ) -> AgentResult < ( ) > {
868
892
rustls:: crypto:: CryptoProvider :: install_default ( rustls:: crypto:: aws_lc_rs:: default_provider ( ) )
869
893
. expect ( "Failed to install crypto provider" ) ;
0 commit comments