My Summer on The Foundation Team

Nathaniel Crosby
strava-engineering
Published in
6 min readSep 15, 2022

Hi! My name is Nathaniel and I am a rising Senior at Amherst College studying Computer Science and Math. This summer, I was a Software Engineering intern on the Foundation Team at Strava.

The Foundation team is broken into two “pods”, API/Platform and Infrastructure. I was a member of the Infrastructure Pod which is responsible for designing, developing, maintaining, and improving all of Strava’s infrastructure and tooling in order to keep Strava working properly and support the product teams as they develop features. A major project on the Infrastructure Pod is a migration from Mesos to Kubernetes. Mesos and Kubernetes are container orchestration platforms that are responsible for managing all of our Scala microservices and jobs as they run independently in Docker containers. Back when Strava adopted Mesos it was thought to likely become an industry standard. However, Kubernetes has since grown to become that standard instead. Now Kubernetes has far more support, new features and capabilities. Additionally, many more engineers have experience with Kubernetes.

My Project

The goal of my summer internship was to develop a process that allows engineers to easily migrate our Scala-HTTP services over to Kubernetes. The first few weeks were largely a learning experience. I had to familiarize myself with Kubernetes, Helm, Strava’s codebase, and how to deploy services. Helm is a Kubernetes specific tool that allows you to easily manage Kubernetes deployments. Essentially, it lets you create generalized yaml manifests, known as Helm Charts, for a type of deployment, such as a Scala-thrift service. A Helm Chart allows you to template Kubernetes Objects, package them together, and pass in values specific to the deployment (more info here: https://helm.sh/docs/topics/charts/). Helm makes it simple to deploy releases (which is what they call specific deployments of a Chart) and when the Chart is modified or values are changed, you can easily upgrade the release as it is running. If a mistake is made, you can rollback to a previous deployment. Prior to my internship, Noa, my Strava buddy, had created a Helm chart for Scala-thrift services. This chart allowed us to deploy any of our Scala-thrift services while only needing to pass in the configuration values that are unique to that service. These would be things such as the service name, docker image, and the cpu/memory resources required.

Here is an example of a service, posthole, being deployed from a Helm chart. All of the templates (top) are generated into Kubernetes Objects (bottom).

Scala-HTTP services are similar to Scala-thrift services except that they need a hostname. In Kubernetes, a hostname is created through an Ingress object. We use ExternalDNS and AWS to help us create and maintain our DNS. Within this setup, an Ingress will create an EC2 load balancer in AWS as well as update our routing (in AWS Route53) so that the hostname will point to the load balancer and then the load balancer will point to the EKS deployment. So, I added this Ingress functionality to the existing Helm Chart, and then modified our deployment process so that if the user specified a hostname, we would create an Ingress and add the associated routing ports. After testing on a few different services, we determined that it was successful.

This is a diagram showing how an ingress manages a load balancer which accepts traffic and passes it to the Service running in Kubernetes. For Source/More info: https://kubernetes.io/docs/concepts/services-networking/ingress/

Once we had created a way to add the hostname, the next step was to improve our deployment process so that it used only Helm commands. Previously, we had been using a mix of Helm and kubectl (the standard Kubernetes command line tool) which meant that the maintainability and simplicity of Helm releases was being lost. To make this change, I modified paasage (Platform as a service — paas), our command line tool, implemented in Python, that engineers use to deploy their services. We first changed the deploy command from kubectl to Helm, and then added upgrade, rollback and uninstall commands. We made the decision to keep the existing configuration file types and formatting from Mesos while we transition so that engineers don’t have to learn new commands and file structure for Helm while also trying to migrate services. Therefore, we translated these configuration (.conf) files into values (.yaml) files that were usable by Helm and created paasage commands to call specific Helm commands, taking care of some more complex options. Once this was complete, we were able to easily deploy our Scala-HTTP services to Kubernetes. The last step was to document this process so that other engineers could easily figure out how to migrate their team’s services.

After this work, I started a similar process for CronJobs. CronJobs are specific programs, tasks, or jobs that we want to run on a regular schedule. As an example, calculating stats for clubs or deleting expired tokens in a database are important jobs that need to run once every day. As with our Scala services, the first step was creating a Helm Chart. The next steps were testing with some of our CronJobs, debugging the Helm Chart, developing an easy deployment process with paasage, and documenting for other engineers.

Strava Jams

A major highlight of my internship was Strava Jams week. This is essentially a week-long hackathon where engineers are able to put aside their usual work and focus completely on whatever ideas they have to improve Strava. I worked on a Strava Spotify integration. This is a feature that I always thought would be interesting because I was always curious about which songs I run fastest to. We weren’t able to finish the integration but we were able to create a new Scala microservice (musique) to query the Spotify API for song data during an activity and store it in a database. We were also able to create a feature to add songs to video. Hopefully this integration gets built out more in the future and we are able to fully integrate music into Strava. I really enjoyed being able to step outside of my project work and connect with engineers and interns from other teams to work on a feature that we were all passionate about. It was also inspiring to see all of the work the other Jams teams had done and all of their creative ideas for improving Strava as a product and company.

Conclusion

I am in the top right just before running the Strava Mile with some other Boston Area Strava employees.

Throughout my project work, I received significant mentorship and guidance from Phani (my manager), Lulu (my mentor), and Noa (my Strava buddy) as well as other Foundation team members. I also gained a lot of insight from engineers on various other teams who helped me figure out how to test their services or who met with me to explain what they are working on and how it fits into Strava’s goals. Throughout my internship, I was able to learn a lot about infrastructure technologies, the value of simple and automated processes, software engineering best practices, as well as anything else I was interested in such as Security, Data, Machine Learning, and more. I really appreciate and am thankful for everyone’s willingness to help me learn and support my work. I think it is a testament to the inclusive and cooperative culture here at Strava which made it a great place to be a curious intern!

--

--