Synchronizing the OSM sidecar with the application container
    • Dark
      Light
    • PDF

    Synchronizing the OSM sidecar with the application container

    • Dark
      Light
    • PDF

    Article Summary

    #ServerlessTips - Open Service Mesh
    Author: Stephane Eyskens, Azure MVP

    Sidecar-based solutions can sometimes cause problems when the application needs the sidecar to function correctly. Any sidecar that is based on the ambassador pattern is likely to create such dependency. In June 2023, sidecars do not have any special status in K8s and are just considered ordinary containers. Because of this, there is no guarantee that the sidecar container starts BEFORE the application container.

    In an ideal world, you’d prefer your application container to be agnostic to whether it is injected or not by a sidecar. You’d prefer not to have to handle anything. This is for instance the case with init containers, which have a special status in K8s and are guaranteed to terminate before your application starts.

    Therefore, you might be in trouble when your application starts before the sidecar and performs network calls towards other meshed services, which will require the app to present its client certificate to authenticate against the target service.

    There are multiple techniques available, which can help you deal with this problem. Here is an example of a .NET console running as a K8s job, and that checks weather OSM’s sidecar (envoy) is ready before the app starts performing network calls.

    // See https://aka.ms/new-console-template for more information 
    
     
    
    using Microsoft.Extensions.DependencyInjection; 
    
    using Polly; 
    
    using Polly.Contrib.WaitAndRetry; 
    
    using System.Net.Http; 
    
     
    
    var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds( 
    
        Convert.ToInt16(Environment.GetEnvironmentVariable("interval"))),  
    
        retryCount: Convert.ToInt16(Environment.GetEnvironmentVariable("maxRetries")));  
    
    var retryPolicy = Policy 
    
    .Handle<Exception>() 
    
    .WaitAndRetryAsync(delay); 
    
     
    
    // wait for sidecar to be ready if any 
    
    if (Environment.GetEnvironmentVariable("PROXY") == "true" && 
    
        !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("proxyEndpoint"))) 
    
    { 
    
        await retryPolicy.ExecuteAsync(() => CallProxyEndpoint( 
    
            string.Concat(Environment.GetEnvironmentVariable("proxyEndpoint"), "ready"))); 
    
    } // will crash if ready is not ready after n attempts in this case. 
    
     
    
    // job itself 
    
    Console.WriteLine("Hey I'm a job, ready to leverage OSM"); 
    
     
    
    // job completion 
    
    if(Environment.GetEnvironmentVariable("proxy") == "true" && 
    
        !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("proxyEndpoint"))) 
    
    { 
    
        await retryPolicy.ExecuteAsync(()=> CallProxyEndpoint( 
    
            string.Concat(Environment.GetEnvironmentVariable("proxyEndpoint"), "quitquitquit")));             
    
    } 
    
     
    
    static async Task<string> CallProxyEndpoint(string endpoint) 
    
    { 
    
        using (HttpClient client = new HttpClient()) 
    
        { 
    
            return (await client.PostAsync(endpoint, null)).StatusCode.ToString(); 
    
        }       
    
         
    
    } 
    

    This demo code relies on Polly, a .NET library which helps you retrying failed requests. It first retrieves the max retry count and the interval as environment variables from the deployment. Of course, you should add some error handling here. Then, it starts by checking whether envoy is available and ready. This is done by calling http://127.0.0.0:15000/ready , which is Envoy’s admin API. The value is passed through an environment variable as well. Upon a non-successful return, the job will retry n times. The part in the middle, is the job itself and the last part is a way to gracefully stop envoy’s container by calling the /quitquit endpoint.

    MicrosoftTeams-image 491


    Was this article helpful?