Push vs. Pull in GitOps: Is There Really a Difference?
GitOps existed long before someone gave it a name. Ever since the first infrastructure-as-code tools emerged, people figured out that it makes a lot of sense to version control the environment definitions and automate the execution of changes. You could say those early pioneers were using Git to do ops. Or you might just call it GitOps. Just like with agile, DevOps or cloud native, often folks with an engineering bent may ask, “Do we really need another marketing buzzword?” As someone who is both an engineer and a marketer, I’d argue that the term GitOps arises more from an engineering need than a marketing one.
A fundamental tenet of software engineering is the practice of abstraction. We abstract repeatable steps into functions, functions into libraries, libraries into frameworks, then we build those frameworks together into tools, and you keep abstracting on and on until you get Kubernetes. This is quite similar to the concept of using abstraction in our language. You can use one word, “GitOps,” as a simple interface to a much richer and deeper set of meanings.
However, just as trouble can arise when you know how to call the API but you don’t understand the underlying execution, so too can invoking GitOps return unexpected results.
This is certainly the case for the two major flavors of GitOps: “push” and “pull.” When using the term “GitOps,” some folks are very explicit about which style they’re referring to, while others use the term more generally to mean either “push” or “pull.”
So, is there really any difference between push and pull GitOps?
Yes, there is. You can stop reading now.
But, if you want to know what the difference is and why it matters, stick around to find out.
Push: The Ol’ Reliable GitOps
In this style, you use a CI/CD (continuous integration/continuous delivery) pipeline to push changes to your environment. The pipeline is triggered by the code commit or merge.
Why Should You Push?
Simplicity: Because push uses well-understood CI/CD tooling, it’s going to be the most accessible to the broadest set of engineers in your organization. This often means you can get started more quickly and have a broader pool of collaboration.
Flexibility: Today, most pull-style GitOps agents only run in Kubernetes. If you want to deploy to anything other than Kubernetes, you’ll need to push the configuration to that environment. There is a possibility of using a pull GitOps agent, running inside a Kubernetes cluster, to orchestrate deployment to external targets — such as VMs and bare metal — but ultimately you are then back to doing push. The agent is pushing to those environments. You end up needing to manage many of the same security concerns of storing credentials external to the environment and opening network firewall ports to allow the inbound connections.
Efficiency: Standardizing on the same deployment methodology for both your cloud native and traditional workloads can make you more efficient. By reducing cognitive overhead, you make onboarding and training new team members easier, while ensuring existing team members focus on solving problems instead of understanding multiple technologies.
Optimized bandwidth: Having a Kubernetes agent continually polling your Git repo for changes may not be a problem with a few clusters, but at scale, you can experience a meaningful consumption of network resources. Additionally, your Git and container registry tooling can come under significant load if it needs to process requests from hundreds of clusters continually polling for state. You could reduce your polling interval, but then you also increase latency between code commit and deployment. With push-style GitOps, you get the best of both worlds where you have fast, low-latency deployments while minimally taxing your network and tooling.
Pull: The New Kid on GitOps
With pull GitOps, an agent running inside your environment continually polls your Git repo and/or container registry for changes. When it detects a mismatch between the defined state and the running state, the agent pulls the defined configuration into the environment.
When Should You Pull?
Cloud native: If all or the majority of your workloads are running in Kubernetes, then using an agent to pull in deployments can be the simple and efficient choice. Using and managing your CD agent is done in a similar way to all of your other Kubernetes operators.
Security: You can enjoy reduced security and compliance risk with pull GitOps. Because the CD agent is running inside of the cluster, there’s no need to store credentials in your external CI. Similarly, you can reduce or eliminate the holes in your firewall that allow inbound connections.
Consistency: Push GitOps typically only works in one direction, from Git repo to environment. Pull GitOps work in the opposite direction as well. Not only can an agent poll your Git repo and container registry for changes, it can also compare the state of the cluster to the defined state in Git. This can detect and remediate configuration drift in the event that changes are made to the cluster manually or from other sources. Push-style CI/CD can be set up to regularly poll your environment, compare running state to defined state and revert to the defined state in the event of configuration drift, but this is something extra you need to set up. Most Pull GitOps agents come with this two-way comparison as a feature you get to take advantage of simply by using the agent without additional setup.
The Bottom Line
At the end of the day, there’s no need to be overly strict. You can have some push and pull (pun intended) when it comes to how you practice GitOps. Weighing the needs of your team or organization with the pros and cons of each approach will help you decide to employ one or both of them. While each style is different, both will net you benefits such as the increased collaboration and compliance that comes with managing operations via merge request/pull request and the increased stability and resiliency that comes with automating your infrastructure and deployments.