{"id":251,"date":"2020-10-05T08:30:30","date_gmt":"2020-10-05T07:30:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/sustainable-software\/?p=251"},"modified":"2020-10-09T16:59:46","modified_gmt":"2020-10-09T15:59:46","slug":"carbon-aware-kubernetes","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/sustainable-software\/carbon-aware-kubernetes\/","title":{"rendered":"Carbon-Aware Kubernetes"},"content":{"rendered":"<p>If you are running microservices these days there is a high probability you are managing them with <a href=\"http:\/\/kubernetes.io\">Kubernetes<\/a>. Kubernetes makes container management easy and its websites boasts of \u201cPlanet Scale\u201d, \u201cNever Outgrow\u201d, and \u201cRun Anywhere\u201d as some of its key features. As a Sustainable Software Engineer, I read those phrases as more of a warning of runaway infrastructure that consumes with no boundary or regard to the impact on the planet or checkbook. The good news is that Kubernetes is built in a way that it can make carbon-aware decisions balanced against the technical requirements of the system. This post will step through an example of how to extend the Kubernetes Scheduler to take advantage of the natural fluctuations in carbon intensities in our existing power grids to minimize the amount of carbon in the atmosphere that your Kubernetes cluster is responsible for.<\/p>\n<h2>System Overview<\/h2>\n<p><figure id=\"attachment_252\" aria-labelledby=\"figcaption_attachment_252\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1024x481.jpg\" alt=\"Kubernetes components and architecture\" width=\"640\" height=\"301\" class=\"size-large wp-image-252\" srcset=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1024x481.jpg 1024w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-300x141.jpg 300w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-768x361.jpg 768w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1536x721.jpg 1536w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture.jpg 1542w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><figcaption id=\"figcaption_attachment_252\" class=\"wp-caption-text\">The core components of Kubernetes<\/figcaption><\/figure><\/p>\n<p>The bulk of the functionality comes from the Kubernetes Scheduler itself and a research paper titled &#8220;<a href=\"http:\/\/ceur-ws.org\/Vol-2382\/ICT4S2019_paper_28.pdf\">A Low Carbon Kubernetes Scheduler<\/a>&#8220;. In short, the Scheduler takes Pods (one or more of your containers) and assigns them to run on Nodes (virtual or physical machines). It does a good job on its own of placing Pods to keep an even distribution across Nodes and ensure enough resources (memory, CPU, etc.) are available to run workloads. However, the Scheduler also lets you define your own rules for how to assign Nodes to Pods. This is where we can inject carbon intensity data as another factor for the Scheduler to use when placing Pods.\u202f<\/p>\n<p>Carbon intensity data for electrical grids around the world is available through APIs like <a href=\"https:\/\/www.watttime.org\/\">WattTime<\/a>. They provide a Marginal Operating Emissions Rate (MOER) value that represents the pounds of carbon emitted to create a megawatt of energy\u200a\u2014\u200athe lower the MOER, the cleaner the energy. <a href=\"https:\/\/www.watttime.org\/api-documentation\/#introduction\">WattTime\u2019s API<\/a> provides both a real-time and projected carbon intensity value for a location like zip code or Lat\/Lng coordinate. We can query the API to get the carbon intensity of the location of each of our Nodes and feed this to the Scheduler\u2019s algorithm to make a carbon-aware decision about where to place the new Pod.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/dubrie\/ea5df4c831d3a240061262eda7bf1aae\" target=\"_blank\" rel=\"noopener noreferrer\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1-300x216.jpg\" alt=\"Sample scheduler YAML file for carbon-aware Kubernetes\" width=\"300\" height=\"216\" class=\"alignright size-medium wp-image-253\" srcset=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1-300x216.jpg 300w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1-768x554.jpg 768w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/Capture-1.jpg 788w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a> With a MOER value assigned to each Node, we need to account for assigning a weight across multiple Nodes. A simplified approach is to take the MOER value of an individual node and divide it by the total MOER values across all nodes to get a normalized percentage weighting of each Node. Save these weightings to a YAML file and by applying them as a Priority for the Scheduler, your Pods will now be assigned to Nodes with lower MOER values where possible. This <a href=\"https:\/\/gist.github.com\/dubrie\/ea5df4c831d3a240061262eda7bf1aae\">sample YAML file<\/a> should be periodically updated as carbon intensities change and re-applied to the Scheduler. Executing the weighting calculation as its own process will allow you to add additional factors to your weighting algorithm, like latency or predicted MOER values.\u202f<\/p>\n<p>These three pieces together (Scheduler, Carbon Intensity Data, Weighting Algorithm) allows any Kubernetes instance to become carbon aware. It can take advantage of natural fluctuations in carbon intensity to ensure your application requires the least amount of carbon to meet your business and customer needs. There are a lot of positive changes in carbon reduction, having an automated way of shifting your workloads around like this allows you to quickly take advantage of improvements and help reduce demand on higher carbon emitting sources.<\/p>\n<h2>Specific Comparison of Regions<\/h2>\n<p>Kubernetes can run physical and virtual machines anywhere but let\u2019s look at a specific scenario using Azure. Let\u2019s say you run some Linux microservices in East US that consists of 5 D4as v4 machines. According to <a href=\"https:\/\/azure.microsoft.com\/en-us\/pricing\/details\/virtual-machines\/linux\/\">current prices<\/a> you would be paying about $0.96\/hour to run them in the East US region. The MOER value for East US fluctuates but averages about 1550 lbs of CO2\/megawatt. By comparison, the West US region MOER value stays around 850 lbs of CO2\/megawatt or a little more than half of what East US emits for the same machine type. Your costs for these machines in West US are $1.12\/hour so <em>you will pay a small premium to cut your carbon emissions roughly in half<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/US-Carbon-Comparison-1.jpg\" alt=\"Carbon comparison of East US and West US Azure regions\" width=\"474\" height=\"104\" class=\"aligncenter size-full wp-image-264\" srcset=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/US-Carbon-Comparison-1.jpg 474w, https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/US-Carbon-Comparison-1-300x66.jpg 300w\" sizes=\"(max-width: 474px) 100vw, 474px\" \/><\/p>\n<p>Let take the same scenario as above but this time using a couple regions in Europe: UK South and North Europe. UK South offers D4as v4 machines at $0.222 per hour and North Europe at $0.214 per hour currently. However, the MOER values for the two are much closer at 965 lbs of CO2\/megawatt for UK South and 1114 lbs of CO2\/megawatt for North Europe. In this scenario, running machines in UK South will cost a little under 4% more but save 149 pounds of carbon (or more than <a href=\"https:\/\/www.epa.gov\/energy\/greenhouse-gas-equivalencies-calculator\">8,600 smartphone charges<\/a>) for each megawatt you consume. \u202f<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-content\/uploads\/sites\/60\/2020\/10\/EU-Carbon-Comparison.jpg\" alt=\"Carbon comparison of UK South and North Europe Azure regions\" width=\"478\" height=\"126\" class=\"aligncenter size-full wp-image-263\" \/><\/p>\n<p>It\u2019s worth noting that both VM prices and MOER values will fluctuate over time, but that is also the point. While it may be about 50% less carbon to run in West US compared to East US now, if the sun isn\u2019t shining or the wind isn\u2019t blowing those numbers will move closer together. Electrical grids are adding more renewable energy all the time and are starting to remove heavy polluting coal plants so these MOER numbers will (hopefully) come down over time.\u202fMicrosoft is helping this trend by announcing a <a href=\"https:\/\/news.microsoft.com\/europe\/2019\/05\/29\/building-for-the-future-microsofts-new-swedish-datacentres-have-sustainability-firmly-in-mind\/\">new datacenter in Sweden<\/a> that will be powered by 100 percent renewable energy sources. Being mindful of your carbon consumption and how your system is able to evolve and shift to be aware of those changes is one of the primary drivers of Sustainable Software Engineering.<\/p>\n<h2>Potential Issues with This Design<\/h2>\n<p>This solution is focused on a narrow, simplified use case. Your scenario is likely more complex than this, but with careful consideration it is still applicable. As a Sustainable Software Engineer it is important to include sustainability in the conversation and find the right balance. Factors like data sovereignty, latency, and the complexity of shifting infrastructure around should be taken into consideration before going down this path.<\/p>\n<p><strong>Data Sovereignty<\/strong><\/p>\n<p>Whether it is political or corporate policy, there are often restrictions on where you can transmit and store data. Shifting virtual machines around automatically has the potential to violate these rules. In this approach it is important to know these restrictions and limit the regions available in the weighting algorithm to only those that you can legally use. If your system requires tight control of data, it may be too limiting to take full advantage of carbon intensity fluctuations.<\/p>\n<p><strong>Latency<\/strong><\/p>\n<p>In the examples above, we compared East US and West US regions by the dimensions of cost and carbon intensity. If the bulk of your customers are on the east coast of the United States, switching to West US could add a noticeable amount of latency to the request and impact those customers. One approach is to use this for asynchronous workloads that can better absorb the additional latency, so it is not impactful to customers. Another option is to adjust the weighting algorithm to account for latencies in its calculation, reducing the weighting factor based on how much latency a regions would add for your typical user. Your specific business rules can guide if this is an appropriate choice.<\/p>\n<p><strong>Complexity of a Shifting Infrastructure<\/strong><\/p>\n<p>If you are moving resources around to different regions to take advantage of shifting carbon intensities, that can cause a lot of additional complexity in your maintenance and operations. Kubernetes is inherently designed to have ephemeral resources so if you are already running it then you shouldn\u2019t need to adjust much here. You will want to pay specific attention to the amount of churn in your Pods and adjust the weightings appropriately for your capacity requirements. Ensure you are shipping any logs and metrics you need off the machines themselves in case they go away.\u202f<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are running microservices these days there is a high probability you are managing them with Kubernetes. Kubernetes makes container management easy and its websites boasts of \u201cPlanet Scale\u201d, \u201cNever Outgrow\u201d, and \u201cRun Anywhere\u201d as some of its key features. As a Sustainable Software Engineer, I read those phrases as more of a warning [&hellip;]<\/p>\n","protected":false},"author":36839,"featured_media":271,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[22],"tags":[75,74,73,72,62],"class_list":["post-251","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sustainable-software-engineering","tag-azure","tag-carbon-intensity","tag-carbon-aware","tag-kubernetes","tag-sustainability"],"acf":[],"blog_post_summary":"<p>If you are running microservices these days there is a high probability you are managing them with Kubernetes. Kubernetes makes container management easy and its websites boasts of \u201cPlanet Scale\u201d, \u201cNever Outgrow\u201d, and \u201cRun Anywhere\u201d as some of its key features. As a Sustainable Software Engineer, I read those phrases as more of a warning [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/posts\/251","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/users\/36839"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/comments?post=251"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/posts\/251\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/media\/271"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/media?parent=251"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/categories?post=251"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/sustainable-software\/wp-json\/wp\/v2\/tags?post=251"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}