{"componentChunkName":"component---src-templates-blog-post-js","path":"/post/karpenter","result":{"data":{"headerImage":{"childImageSharp":{"fluid":{"aspectRatio":3.3992537313432836,"src":"/static/b72d38f0a9a131a445c0798c8f11b233/85c19/blog-post-intro.png","srcSet":"/static/b72d38f0a9a131a445c0798c8f11b233/c95ef/blog-post-intro.png 911w,\n/static/b72d38f0a9a131a445c0798c8f11b233/6d938/blog-post-intro.png 1822w,\n/static/b72d38f0a9a131a445c0798c8f11b233/85c19/blog-post-intro.png 3635w","srcWebp":"/static/b72d38f0a9a131a445c0798c8f11b233/bbedc/blog-post-intro.webp","srcSetWebp":"/static/b72d38f0a9a131a445c0798c8f11b233/8f106/blog-post-intro.webp 911w,\n/static/b72d38f0a9a131a445c0798c8f11b233/4b1a2/blog-post-intro.webp 1822w,\n/static/b72d38f0a9a131a445c0798c8f11b233/bbedc/blog-post-intro.webp 3635w","sizes":"(max-width: 3635px) 100vw, 3635px"}}},"relatedPosts":{"nodes":[{"fields":{"slug":"/blog-aws-kubernetes/"},"frontmatter":{"url":"aws-kubernetes/part-1","title":"The State of Kubernetes in AWS: Persistent Data Storage, Application Engineering and More","description":"When it comes to orchestrating containerized workloads, there are several options in the market, with [Kubernetes](https://kubernetes.io) being the most adopted and sought-after solution.","tags":["AWS","Kubernetes"],"date":"2022-12-20T16:44:23.317Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.5,"src":"/static/eb8228db77951dd583fd607fb3b3d3bd/836e2/kubernetes-and-aws.jpg","srcSet":"/static/eb8228db77951dd583fd607fb3b3d3bd/6e81a/kubernetes-and-aws.jpg 120w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/fbe0e/kubernetes-and-aws.jpg 240w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/836e2/kubernetes-and-aws.jpg 480w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/94285/kubernetes-and-aws.jpg 720w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/b1cc5/kubernetes-and-aws.jpg 960w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/097fa/kubernetes-and-aws.jpg 1920w","srcWebp":"/static/eb8228db77951dd583fd607fb3b3d3bd/35871/kubernetes-and-aws.webp","srcSetWebp":"/static/eb8228db77951dd583fd607fb3b3d3bd/83552/kubernetes-and-aws.webp 120w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/2b5a3/kubernetes-and-aws.webp 240w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/35871/kubernetes-and-aws.webp 480w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/9754a/kubernetes-and-aws.webp 720w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/fcc10/kubernetes-and-aws.webp 960w,\n/static/eb8228db77951dd583fd607fb3b3d3bd/30cf3/kubernetes-and-aws.webp 1920w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/kubernetes-node-management/"},"frontmatter":{"url":"karpenter","title":"Karpenter - A New Way to Manage Kubernetes Node Groups","description":"One of the most common discussions that happen when adopting Kubernetes is around autoscaling. You can autoscale your workloads horizontally or vertically, but the main challenge has always been the nodes.\n","tags":["Kubernetes","AWS"],"date":"2022-01-20T00:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.9047619047619047,"src":"/static/e0d4e328e64d982af16b722b7165263b/b460a/aws-karpenter.png","srcSet":"/static/e0d4e328e64d982af16b722b7165263b/d966b/aws-karpenter.png 120w,\n/static/e0d4e328e64d982af16b722b7165263b/67196/aws-karpenter.png 240w,\n/static/e0d4e328e64d982af16b722b7165263b/b460a/aws-karpenter.png 480w,\n/static/e0d4e328e64d982af16b722b7165263b/9a8d7/aws-karpenter.png 720w,\n/static/e0d4e328e64d982af16b722b7165263b/6e898/aws-karpenter.png 960w,\n/static/e0d4e328e64d982af16b722b7165263b/6050d/aws-karpenter.png 1200w","srcWebp":"/static/e0d4e328e64d982af16b722b7165263b/35871/aws-karpenter.webp","srcSetWebp":"/static/e0d4e328e64d982af16b722b7165263b/83552/aws-karpenter.webp 120w,\n/static/e0d4e328e64d982af16b722b7165263b/2b5a3/aws-karpenter.webp 240w,\n/static/e0d4e328e64d982af16b722b7165263b/35871/aws-karpenter.webp 480w,\n/static/e0d4e328e64d982af16b722b7165263b/9754a/aws-karpenter.webp 720w,\n/static/e0d4e328e64d982af16b722b7165263b/fcc10/aws-karpenter.webp 960w,\n/static/e0d4e328e64d982af16b722b7165263b/9000d/aws-karpenter.webp 1200w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/aws-kubernetes-part-2/"},"frontmatter":{"url":"aws-kubernetes/part-2","title":"The Current State of Kubernetes on AWS: Kubernetes Security, Scalability, Performance Engineering & More, Part 2","description":"In the first part of our two-part post on the current state of Kubernetes in AWS, we discussed how Kubernetes can help you handle stateful workloads with persistent data storage and standardize your application and data engineering approaches.","tags":["AWS","Kubernetes"],"date":"2021-12-09T08:30:41.061Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.5,"src":"/static/dddeb31efb8e1c04a57b32e10aa14653/836e2/kubernetes-security.jpg","srcSet":"/static/dddeb31efb8e1c04a57b32e10aa14653/6e81a/kubernetes-security.jpg 120w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/fbe0e/kubernetes-security.jpg 240w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/836e2/kubernetes-security.jpg 480w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/94285/kubernetes-security.jpg 720w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/b1cc5/kubernetes-security.jpg 960w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/097fa/kubernetes-security.jpg 1920w","srcWebp":"/static/dddeb31efb8e1c04a57b32e10aa14653/35871/kubernetes-security.webp","srcSetWebp":"/static/dddeb31efb8e1c04a57b32e10aa14653/83552/kubernetes-security.webp 120w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/2b5a3/kubernetes-security.webp 240w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/35871/kubernetes-security.webp 480w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/9754a/kubernetes-security.webp 720w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/fcc10/kubernetes-security.webp 960w,\n/static/dddeb31efb8e1c04a57b32e10aa14653/30cf3/kubernetes-security.webp 1920w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/smb-cloud-adoption/"},"frontmatter":{"url":"smb-cloud-adoption","title":"How to Streamline & Accelerate Your SMB Cloud Adoption","description":"The most successful businesses in today's fast-changing, digitally fueled society are those who take advantage of innovation and are data-driven. However, small and midsize businesses (SMBs) typically have fewer resources to fund the significant upfront investment that is often required to innovate, putting them at a disadvantage.","tags":["AWS","SMB","Cloud Adoption solution"],"date":"2021-10-20T19:15:51.989Z","image":{"childImageSharp":{"fluid":{"aspectRatio":2.3076923076923075,"src":"/static/f00f7616828543f0112e7c8aa9c08b01/836e2/smb-cloud-adoption.jpg","srcSet":"/static/f00f7616828543f0112e7c8aa9c08b01/6e81a/smb-cloud-adoption.jpg 120w,\n/static/f00f7616828543f0112e7c8aa9c08b01/fbe0e/smb-cloud-adoption.jpg 240w,\n/static/f00f7616828543f0112e7c8aa9c08b01/836e2/smb-cloud-adoption.jpg 480w,\n/static/f00f7616828543f0112e7c8aa9c08b01/94285/smb-cloud-adoption.jpg 720w,\n/static/f00f7616828543f0112e7c8aa9c08b01/b1cc5/smb-cloud-adoption.jpg 960w,\n/static/f00f7616828543f0112e7c8aa9c08b01/097fa/smb-cloud-adoption.jpg 1920w","srcWebp":"/static/f00f7616828543f0112e7c8aa9c08b01/35871/smb-cloud-adoption.webp","srcSetWebp":"/static/f00f7616828543f0112e7c8aa9c08b01/83552/smb-cloud-adoption.webp 120w,\n/static/f00f7616828543f0112e7c8aa9c08b01/2b5a3/smb-cloud-adoption.webp 240w,\n/static/f00f7616828543f0112e7c8aa9c08b01/35871/smb-cloud-adoption.webp 480w,\n/static/f00f7616828543f0112e7c8aa9c08b01/9754a/smb-cloud-adoption.webp 720w,\n/static/f00f7616828543f0112e7c8aa9c08b01/fcc10/smb-cloud-adoption.webp 960w,\n/static/f00f7616828543f0112e7c8aa9c08b01/30cf3/smb-cloud-adoption.webp 1920w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/public-sector-cloud-adoption/"},"frontmatter":{"url":"public-sector-cloud-adoption","title":"How to Transform Your Public Sector Organization with Cloud Adoption      ","description":"Whether you work in government, education, non-profit, or healthcare, we know that your public sector organization is unique - and so are its challenges, from budgetary restrictions to significant governance, security and compliance requirements.","tags":["Public Sector","AWS"],"date":"2021-08-12T20:38:56.252Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.791044776119403,"src":"/static/c010c944ab047a7187b81b6ba82a74b9/836e2/shutterstock_1724551933.jpg","srcSet":"/static/c010c944ab047a7187b81b6ba82a74b9/6e81a/shutterstock_1724551933.jpg 120w,\n/static/c010c944ab047a7187b81b6ba82a74b9/fbe0e/shutterstock_1724551933.jpg 240w,\n/static/c010c944ab047a7187b81b6ba82a74b9/836e2/shutterstock_1724551933.jpg 480w,\n/static/c010c944ab047a7187b81b6ba82a74b9/94285/shutterstock_1724551933.jpg 720w,\n/static/c010c944ab047a7187b81b6ba82a74b9/b1cc5/shutterstock_1724551933.jpg 960w,\n/static/c010c944ab047a7187b81b6ba82a74b9/4af19/shutterstock_1724551933.jpg 6518w","srcWebp":"/static/c010c944ab047a7187b81b6ba82a74b9/35871/shutterstock_1724551933.webp","srcSetWebp":"/static/c010c944ab047a7187b81b6ba82a74b9/83552/shutterstock_1724551933.webp 120w,\n/static/c010c944ab047a7187b81b6ba82a74b9/2b5a3/shutterstock_1724551933.webp 240w,\n/static/c010c944ab047a7187b81b6ba82a74b9/35871/shutterstock_1724551933.webp 480w,\n/static/c010c944ab047a7187b81b6ba82a74b9/9754a/shutterstock_1724551933.webp 720w,\n/static/c010c944ab047a7187b81b6ba82a74b9/fcc10/shutterstock_1724551933.webp 960w,\n/static/c010c944ab047a7187b81b6ba82a74b9/d486d/shutterstock_1724551933.webp 6518w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/automate-deployment-to-aws-with-github-actions/"},"frontmatter":{"url":"automate-deployment-to-aws-with-github-actions","title":"Automate Deployment to AWS with GitHub Actions","description":"In previous posts we have looked at the popularity of GitOps and a number of tools available to implement GitOps. Among the tools there are GitHub Actions. Given the popularity of GitHub in both enterprises and open-sourced communities, let's walk through how to set up the new feature; GitHub Actions.","tags":["AWS","DevOps"],"date":"2020-02-18T17:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.5,"src":"/static/671506745a2600616b877b8ba95908eb/836e2/github-actions-blog.jpg","srcSet":"/static/671506745a2600616b877b8ba95908eb/6e81a/github-actions-blog.jpg 120w,\n/static/671506745a2600616b877b8ba95908eb/fbe0e/github-actions-blog.jpg 240w,\n/static/671506745a2600616b877b8ba95908eb/836e2/github-actions-blog.jpg 480w,\n/static/671506745a2600616b877b8ba95908eb/94285/github-actions-blog.jpg 720w,\n/static/671506745a2600616b877b8ba95908eb/b1cc5/github-actions-blog.jpg 960w,\n/static/671506745a2600616b877b8ba95908eb/41bee/github-actions-blog.jpg 5200w","srcWebp":"/static/671506745a2600616b877b8ba95908eb/35871/github-actions-blog.webp","srcSetWebp":"/static/671506745a2600616b877b8ba95908eb/83552/github-actions-blog.webp 120w,\n/static/671506745a2600616b877b8ba95908eb/2b5a3/github-actions-blog.webp 240w,\n/static/671506745a2600616b877b8ba95908eb/35871/github-actions-blog.webp 480w,\n/static/671506745a2600616b877b8ba95908eb/9754a/github-actions-blog.webp 720w,\n/static/671506745a2600616b877b8ba95908eb/fcc10/github-actions-blog.webp 960w,\n/static/671506745a2600616b877b8ba95908eb/a7c71/github-actions-blog.webp 5200w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/gitops-why-is-it-relevant-now/"},"frontmatter":{"url":"gitops-why-is-it-relevant-now","title":"GitOps - Why is it Relevant Now?","description":"There seems to have been a lot of talk about GitOps just recently. This impression is certainly reinforced by the sessions and booths during KubeCon San Diego late 2019. Regardless of the discipline or services, GitOps was the keyword that was constantly repeated.","tags":["Kubernetes"],"date":"2020-01-21T17:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.3333333333333333,"src":"/static/602b397bd0ef200acbf6007f11c2f3f5/836e2/shutterstock_1019460151-1-.jpg","srcSet":"/static/602b397bd0ef200acbf6007f11c2f3f5/6e81a/shutterstock_1019460151-1-.jpg 120w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/fbe0e/shutterstock_1019460151-1-.jpg 240w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/836e2/shutterstock_1019460151-1-.jpg 480w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/94285/shutterstock_1019460151-1-.jpg 720w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/b1cc5/shutterstock_1019460151-1-.jpg 960w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/405f0/shutterstock_1019460151-1-.jpg 4856w","srcWebp":"/static/602b397bd0ef200acbf6007f11c2f3f5/35871/shutterstock_1019460151-1-.webp","srcSetWebp":"/static/602b397bd0ef200acbf6007f11c2f3f5/83552/shutterstock_1019460151-1-.webp 120w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/2b5a3/shutterstock_1019460151-1-.webp 240w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/35871/shutterstock_1019460151-1-.webp 480w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/9754a/shutterstock_1019460151-1-.webp 720w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/fcc10/shutterstock_1019460151-1-.webp 960w,\n/static/602b397bd0ef200acbf6007f11c2f3f5/cdeed/shutterstock_1019460151-1-.webp 4856w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/setting-up-a-multi-tenant-aws-eks-cluster/"},"frontmatter":{"url":"setting-up-a-multi-tenant-aws-eks-cluster","title":"Setting up a Multi-tenant Amazon EKS cluster: a few things to consider","description":"MyOps prides itself in heavy use of cloud-native technology, and Kubernetes is often the primary platform of choice to run containerized workloads. In this blog we discuss using name space, network policies, Integrating AWS IAM to EKS cluster/workloads, isolation techniques and much more.","tags":["Kubernetes","AWS"],"date":"2019-12-12T17:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.7647058823529411,"src":"/static/242e9209b664bee2a7dc6b090d3a07e1/836e2/setting-up-multi-tenant-aws-eks-cluster.jpg","srcSet":"/static/242e9209b664bee2a7dc6b090d3a07e1/6e81a/setting-up-multi-tenant-aws-eks-cluster.jpg 120w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/fbe0e/setting-up-multi-tenant-aws-eks-cluster.jpg 240w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/836e2/setting-up-multi-tenant-aws-eks-cluster.jpg 480w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/94285/setting-up-multi-tenant-aws-eks-cluster.jpg 720w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/b1cc5/setting-up-multi-tenant-aws-eks-cluster.jpg 960w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/e147c/setting-up-multi-tenant-aws-eks-cluster.jpg 5760w","srcWebp":"/static/242e9209b664bee2a7dc6b090d3a07e1/35871/setting-up-multi-tenant-aws-eks-cluster.webp","srcSetWebp":"/static/242e9209b664bee2a7dc6b090d3a07e1/83552/setting-up-multi-tenant-aws-eks-cluster.webp 120w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/2b5a3/setting-up-multi-tenant-aws-eks-cluster.webp 240w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/35871/setting-up-multi-tenant-aws-eks-cluster.webp 480w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/9754a/setting-up-multi-tenant-aws-eks-cluster.webp 720w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/fcc10/setting-up-multi-tenant-aws-eks-cluster.webp 960w,\n/static/242e9209b664bee2a7dc6b090d3a07e1/b4d70/setting-up-multi-tenant-aws-eks-cluster.webp 5760w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/walkthrough-ecs-local/"},"frontmatter":{"url":"walkthrough-ecs-local","title":"Walkthrough - ECS Local: Bringing ECS to your local environment","description":"As someone who works with AWS on a day-to-day basis, It's important to stay up to date with all the changes and new features of the different services on the platform. That's how one recent announcement caught my eye - The new capability of local testing of ECS.","tags":["Kubernetes","AWS"],"date":"2019-09-17T16:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":2.142857142857143,"src":"/static/12224681f2fd40bf0749423e29cf8d0c/836e2/technology-education-information-handover.jpg","srcSet":"/static/12224681f2fd40bf0749423e29cf8d0c/6e81a/technology-education-information-handover.jpg 120w,\n/static/12224681f2fd40bf0749423e29cf8d0c/fbe0e/technology-education-information-handover.jpg 240w,\n/static/12224681f2fd40bf0749423e29cf8d0c/836e2/technology-education-information-handover.jpg 480w,\n/static/12224681f2fd40bf0749423e29cf8d0c/94285/technology-education-information-handover.jpg 720w,\n/static/12224681f2fd40bf0749423e29cf8d0c/b1cc5/technology-education-information-handover.jpg 960w,\n/static/12224681f2fd40bf0749423e29cf8d0c/0ff54/technology-education-information-handover.jpg 1200w","srcWebp":"/static/12224681f2fd40bf0749423e29cf8d0c/35871/technology-education-information-handover.webp","srcSetWebp":"/static/12224681f2fd40bf0749423e29cf8d0c/83552/technology-education-information-handover.webp 120w,\n/static/12224681f2fd40bf0749423e29cf8d0c/2b5a3/technology-education-information-handover.webp 240w,\n/static/12224681f2fd40bf0749423e29cf8d0c/35871/technology-education-information-handover.webp 480w,\n/static/12224681f2fd40bf0749423e29cf8d0c/9754a/technology-education-information-handover.webp 720w,\n/static/12224681f2fd40bf0749423e29cf8d0c/fcc10/technology-education-information-handover.webp 960w,\n/static/12224681f2fd40bf0749423e29cf8d0c/9000d/technology-education-information-handover.webp 1200w","sizes":"(max-width: 480px) 100vw, 480px"}}}}},{"fields":{"slug":"/opensource-data-lakes-for-the-hybrid-cloud-designing-an-oss-datalake/"},"frontmatter":{"url":"opensource-data-lakes-for-the-hybrid-cloud-designing-an-oss-datalake","title":"OpenSource Data Lake for the Hybrid Cloud - Part 2: Designing an OSS DataLake","description":"In part 1 of this series, we answered the question of WHY Open Source components are often an attractive option when building a data lake of any significant size. In this second installment, we describe HOW to cost-effectively build a data lake out of Open Source components.","tags":["Kubernetes","Big Data"],"date":"2019-08-27T16:00:00.000Z","image":{"childImageSharp":{"fluid":{"aspectRatio":1.6,"src":"/static/107087aec2d3327919bcfb2ab38201da/836e2/datalake-p2.jpg","srcSet":"/static/107087aec2d3327919bcfb2ab38201da/6e81a/datalake-p2.jpg 120w,\n/static/107087aec2d3327919bcfb2ab38201da/fbe0e/datalake-p2.jpg 240w,\n/static/107087aec2d3327919bcfb2ab38201da/836e2/datalake-p2.jpg 480w,\n/static/107087aec2d3327919bcfb2ab38201da/94285/datalake-p2.jpg 720w,\n/static/107087aec2d3327919bcfb2ab38201da/b1cc5/datalake-p2.jpg 960w,\n/static/107087aec2d3327919bcfb2ab38201da/32638/datalake-p2.jpg 6399w","srcWebp":"/static/107087aec2d3327919bcfb2ab38201da/35871/datalake-p2.webp","srcSetWebp":"/static/107087aec2d3327919bcfb2ab38201da/83552/datalake-p2.webp 120w,\n/static/107087aec2d3327919bcfb2ab38201da/2b5a3/datalake-p2.webp 240w,\n/static/107087aec2d3327919bcfb2ab38201da/35871/datalake-p2.webp 480w,\n/static/107087aec2d3327919bcfb2ab38201da/9754a/datalake-p2.webp 720w,\n/static/107087aec2d3327919bcfb2ab38201da/fcc10/datalake-p2.webp 960w,\n/static/107087aec2d3327919bcfb2ab38201da/85285/datalake-p2.webp 6399w","sizes":"(max-width: 480px) 100vw, 480px"}}}}}]},"socials":{"frontmatter":{"socials":{"linkedin":"https://www.linkedin.com/company/myops-yael","github":"https://github.com/opsguru-israel"}}},"markdownRemark":{"html":"<p>One of the most common discussions that happen when <a href=\"/kubernetes-enablement\">adopting Kubernetes</a> is around autoscaling. You can autoscale your workloads horizontally or vertically, but the main challenge has always been the nodes.</p>\n<p>The hypervisor doesn't have visibility into what the container is actually consuming in a virtual machine, nor is it aware of the workload resource requirements, and without that information the cloud provider can't reliably handle the node autoscaling. The solution was to let something that does have that information handle it, and so we have the <a href=\"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler\">Cluster Autoscaler</a>.</p>\n<p>The Cluster Autoscaler automatically adjusts the size of an autoscaling group (ASG), when a pod failed to run in the cluster due to insufficient resources, or when nodes in the cluster are underutilized for a set period of time, and their pods can fit into other existing nodes.</p>\n<p>Looking at the above description, it seems like the Cluster Autoscaler is just fine, and in most cases it is, but what if you need a new type of node that isn't available yet in your cluster's nodegroups?</p>\n<p>Most organizations will have their clusters deployed using some kind of infrastructure as code tool like <a href=\"https://terraform.io\">Terraform</a> or <a href=\"https://aws.amazon.com/cloudformation/\">AWS Cloudformation</a>, which means that updates to this codebase will be necessary when changing the node groups. Configuring details and restrictions of these node groups is not always a straightforward process either.</p>\n<p>New nodes can also take a while to be available to Kubernetes, and once they are available you might still run into racing conditions scheduling pods into these nodes.</p>\n<p>Recently, AWS released <a href=\"https://karpenter.sh\">Karpenter</a> to address these issues and bring a more native approach to managing your cluster nodes.</p>\n<p>Let's take a look at how both solutions work, current pros and cons.</p>\n<h2>Cluster Autoscaler and Karpenter</h2>\n<p><strong>How does the Cluster Autoscaler work?</strong></p>\n<ul>\n<li>We deploy a workload to the cluster</li>\n<li>Kubernetes scheduler could not find a node that will fit our pod</li>\n<li>Pod is marked as <code class=\"language-text\">Pending</code> and <code class=\"language-text\">Unschedulable</code></li>\n<li>Cluster Autoscaler looks for pods in a <code class=\"language-text\">Pending</code> state</li>\n<li>It increases the ASG desired count if the pending pods do not fit in the current nodes</li>\n<li>The ASG creates a new instance</li>\n<li>Instance joins the cluster</li>\n<li>Kubernetes scheduler finds the new node and, if the pod fits in it, assigns the pod to it</li>\n</ul>\n<p>So the Cluster Autoscaler doesn't really deal with the nodes themselves, it just adjusts the AWS ASG and lets AWS take care of everything else on the infrastructure side, and relies on the Kubernetes scheduler to assign the pod to a node.</p>\n<p>While this works, it can introduce a number of failure modes, like a racing condition having a pod being assigned to your new node before your old pod, triggering the whole loop again and leaving your pod pending for a longer period.</p>\n<p><strong>What about Karpenter?</strong></p>\n<p>Karpenter does not manipulate ASGs, it handles the instances directly. Instead of creating code to deploy a new node group, then target your workload to that group, you just deploy your workload, and Karpenter will create an EC2 instance that matches your constraints, if it has a matching Provisioner. A Provisioner in Karpenter is a manifest that describes a node group. You can have multiple Provisioners for different needs, just like node groups.</p>\n<p>Ok, if its like node groups, what is the advantage? The catch is in the way that Karpenter works. Let's do the same exercise we did for the Cluster Autoscaler, but now with Karpenter.</p>\n<ul>\n<li>We deploy a workload to the cluster</li>\n<li>Kubernetes scheduler could not find a node that will fit our pod</li>\n<li>Pod is marked as <code class=\"language-text\">Pending</code> and <code class=\"language-text\">Unschedulable</code></li>\n<li>Karpenter evaluates the resources and constraints of the <code class=\"language-text\">Unschedulable</code> pods against the available Provisioners and creates matching EC2 instances</li>\n<li>Instance(s) joins the cluster</li>\n<li>Karpenter immediately binds the pods to the new node(s) without waiting for the Kubernetes scheduler</li>\n</ul>\n<p>Just by not relying on ASGs and handling the nodes itself, it cuts on the time needed to provision a new node, as it doesn't need to wait for the ASG to respond to a change in its sizing, it can request a new instance in seconds.</p>\n<p>In our tests, a pending pod got a node created for it in 2 seconds, and was running in about 1 minute in average, versus 2 to 5 minutes with the Cluster Autoscaler.</p>\n<p>The possible racing condition we talked about before, is not possible in this model as the pods are immediately assigned to the new nodes.</p>\n<p>Other interesting things the Provisioner can do is setting a ttl for empty nodes, so a node that has no pods, other than DaemonSet pods, is terminated when the ttl is reached.</p>\n<p>It can also ensure nodes are current by enforcing a ttl for the nodes in general, meaning a node is recycled once the ttl is reached.</p>\n<p>Ok! So Karpenter is great, let's dump the Cluster Autoscaler! Not so fast! There is one feature that Karpenter is missing from Cluster Autoscaler, which is rebalancing nodes, the later can drain a node when its utilization falls under a certain treshold and its pods fit in other nodes.</p>\n<h2>Talk is Cheap! Show me the demo!</h2>\n<p>Let's get this running! We're following the getting started guide from <a href=\"https://karpenter.sh\">karpenter.sh</a> with a couple twists.</p>\n<blockquote>\n<p>At the time this post was written Karpenter 0.5.2 was the latest version available.</p>\n</blockquote>\n<p>First the good old warning for all demo code.</p>\n<p>WARNING! This code is for use in testing only, broad permissions are given to Karpenter, and there was no effort in securing the cluster.</p>\n<p>Now go and checkout our git repository from <a href=\"https://github.com/ops-guru/karpenter-blog-post\">https://github.com/ops-guru/karpenter-blog-post</a>.</p>\n<p>We will use <a href=\"https://terraform.io\">Terraform</a>, and <a href=\"https://helm.sh\">Helm</a> to deploy:</p>\n<ul>\n<li>a VPC and Subnets</li>\n<li>an EKS cluster with one node (need to run Karpenter somewhere right?)</li>\n<li>an IAM role to allow Karpenter to manipulate some AWS resources it needs to manage nodes for us (more details on those in the <a href=\"https://karpenter.sh/preview/getting-started/\">Getting Started with Terraform</a> page at Karpenter's website)</li>\n<li>Karpenter using its helm chart with access to its IAM role through <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html\">IAM Roles for Service Accounts</a></li>\n</ul>\n<p>To that end we will first export a couple environment variables.</p>\n<ul>\n<li><code class=\"language-text\">AWS_PROFILE</code> is our AWS cli profile configured with our credentials (if yours are in your default profile you can skip this one)</li>\n<li><code class=\"language-text\">AWS_DEFAULT_REGION</code> to select which region to create resources in</li>\n<li><code class=\"language-text\">CLUSTER_NAME</code> to give our cluster a nice name</li>\n<li><code class=\"language-text\">KUBECONFIG</code> and <code class=\"language-text\">KUBE_CONFIG_PATH</code> to tell kubectl, helm and terraform where our kubeconfig file is (which will be created by terraform for us)</li>\n</ul>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"89698826014756490000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`export AWS_PROFILE=MyOps\nexport AWS_DEFAULT_REGION=ca-central-1\nexport CLUSTER_NAME=myops-karpenter-test\nexport KUBECONFIG=\\${PWD}/kubeconfig_\\${CLUSTER_NAME}\nexport KUBE_CONFIG_PATH=\\${KUBECONFIG}`, `89698826014756490000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\"><span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">AWS_PROFILE</span><span class=\"token operator\">=</span>MyOps\n<span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">AWS_DEFAULT_REGION</span><span class=\"token operator\">=</span>ca-central-1\n<span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">CLUSTER_NAME</span><span class=\"token operator\">=</span>myops-karpenter-test\n<span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">KUBECONFIG</span><span class=\"token operator\">=</span><span class=\"token variable\">${<span class=\"token environment constant\">PWD</span>}</span>/kubeconfig_<span class=\"token variable\">${CLUSTER_NAME}</span>\n<span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\">KUBE_CONFIG_PATH</span><span class=\"token operator\">=</span><span class=\"token variable\">${KUBECONFIG}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Let's create our cluster and deploy Karpenter into it. Init terraform, then check the plan and confirm. EKS cluster creation takes around 10 minutes.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"91243003904100250000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`terraform init\nterraform apply -var cluster_name=\\${CLUSTER_NAME} -var region=\\${AWS_DEFAULT_REGION}`, `91243003904100250000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">terraform init\nterraform apply -var <span class=\"token assign-left variable\">cluster_name</span><span class=\"token operator\">=</span><span class=\"token variable\">${CLUSTER_NAME}</span> -var <span class=\"token assign-left variable\">region</span><span class=\"token operator\">=</span><span class=\"token variable\">${AWS_DEFAULT_REGION}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>Now that you've got some coffee let's talk node groups.</p>\n<p>Our demo will assume we want two node groups in the cluster. One using on-demand instances, another using spot instances.</p>\n<p>How can we do this with Karpenter? We just need to define <a href=\"https://karpenter.sh/preview/concepts/provisioners/\">Provisioners</a> for each of these groups. Instead of rambling about it, let's take a look at the provisioner resources for our two node groups.</p>\n<p>Our on-demand instances are for our cluster addons, we will want a taint to ensure only cluster addons are deployed there. We also want to restrict the node types to m5.large and m5.2xlarge instances in both our availability zones.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"95316433543953680000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`cat <<EOF > node_group_addons.yaml\napiVersion: karpenter.sh/v1alpha5\nkind: Provisioner\nmetadata:\n  name: addons-ondemand\nspec:\n  requirements:\n    - key: node.kubernetes.io/instance-type # If not included, all instance types are considered\n      operator: In\n      values: [&quot;m5.large&quot;, &quot;m5.2xlarge&quot;]\n    - key: &quot;topology.kubernetes.io/zone&quot; # If not included, all zones are considered\n      operator: In\n      values: [&quot;\\${AWS_DEFAULT_REGION}a&quot;, &quot;\\${AWS_DEFAULT_REGION}b&quot;]\n    - key: &quot;karpenter.sh/capacity-type&quot;\n      operator: In\n      values: [&quot;on-demand&quot;]\n  labels: # Kubernetes labels\n    managed-by: karpenter\n    purpose: addons\n  provider:\n    instanceProfile: KarpenterNodeInstanceProfile-\\${CLUSTER_NAME}\n    tags: # AWS EC2 Tags\n      managed-by: karpenter\n  ttlSecondsAfterEmpty: 30 # If a node is empty of non daemonset pods for this ttl, it is removed\n  taints:\n    - key: myops.co.il/addons\n      effect: NoSchedule\nEOF`, `95316433543953680000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\"><span class=\"token function\">cat</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">EOF<span class=\"token bash punctuation\"> <span class=\"token operator\">></span> node_group_addons.yaml</span>\napiVersion: karpenter.sh/v1alpha5\nkind: Provisioner\nmetadata:\n  name: addons-ondemand\nspec:\n  requirements:\n    - key: node.kubernetes.io/instance-type # If not included, all instance types are considered\n      operator: In\n      values: [\"m5.large\", \"m5.2xlarge\"]\n    - key: \"topology.kubernetes.io/zone\" # If not included, all zones are considered\n      operator: In\n      values: [\"<span class=\"token variable\">${AWS_DEFAULT_REGION}</span>a\", \"<span class=\"token variable\">${AWS_DEFAULT_REGION}</span>b\"]\n    - key: \"karpenter.sh/capacity-type\"\n      operator: In\n      values: [\"on-demand\"]\n  labels: # Kubernetes labels\n    managed-by: karpenter\n    purpose: addons\n  provider:\n    instanceProfile: KarpenterNodeInstanceProfile-<span class=\"token variable\">${CLUSTER_NAME}</span>\n    tags: # AWS EC2 Tags\n      managed-by: karpenter\n  ttlSecondsAfterEmpty: 30 # If a node is empty of non daemonset pods for this ttl, it is removed\n  taints:\n    - key: myops.co.il/addons\n      effect: NoSchedule\nEOF</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>What are we looking at?</p>\n<ul>\n<li>Any pods that nodeSelect to <code class=\"language-text\">managed-by: karpenter</code> and tolerates our <code class=\"language-text\">myops.co.il/addons</code> taint, and can fit into a m5.large or m5.2xlarge node will have a node provisioned for it, if needed</li>\n<li>The nodes will be on-demand type nodes</li>\n<li>The nodes will be deployed in either our AZ a or b</li>\n<li>If the node is empty for more than 30 seconds we terminate it</li>\n<li>Kubernetes labels <code class=\"language-text\">managed-by: karpenter</code> and <code class=\"language-text\">purpose: addons</code> will be added to the nodes</li>\n<li>An EC2 tag <code class=\"language-text\">managed-by: karpenter</code> will be applied to the nodes</li>\n</ul>\n<p>Our spot instances are for any other workloads, we will not taint them and we will use c5 instances. Any workloads that can't fit on our initial cluster node (the one created with Terraform), and do not tolerate the <code class=\"language-text\">myops.co.il/addons</code> from the on-demand group, should be scheduled in these nodes.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"488950165151091900\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`cat <<EOF > node_group_general_spot.yaml\napiVersion: karpenter.sh/v1alpha5\nkind: Provisioner\nmetadata:\n  name: spot-general\nspec:\n  requirements:\n    - key: node.kubernetes.io/instance-type # If not included, all instance types are considered\n      operator: In\n      values: [&quot;c5.large&quot;, &quot;c5.2xlarge&quot;]\n    - key: &quot;topology.kubernetes.io/zone&quot; # If not included, all zones are considered\n      operator: In\n      values: [&quot;\\${AWS_DEFAULT_REGION}a&quot;, &quot;\\${AWS_DEFAULT_REGION}b&quot;]\n    - key: &quot;karpenter.sh/capacity-type&quot;\n      operator: In\n      values: [&quot;spot&quot;]\n  labels: # Kubernetes labels\n    managed-by: karpenter\n  provider:\n    instanceProfile: KarpenterNodeInstanceProfile-\\${CLUSTER_NAME}\n    tags: # AWS EC2 Tags\n      managed-by: karpenter\n  ttlSecondsAfterEmpty: 30 # If a node is empty of non daemonset pods for this ttl, it is removed\nEOF`, `488950165151091900`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\"><span class=\"token function\">cat</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">EOF<span class=\"token bash punctuation\"> <span class=\"token operator\">></span> node_group_general_spot.yaml</span>\napiVersion: karpenter.sh/v1alpha5\nkind: Provisioner\nmetadata:\n  name: spot-general\nspec:\n  requirements:\n    - key: node.kubernetes.io/instance-type # If not included, all instance types are considered\n      operator: In\n      values: [\"c5.large\", \"c5.2xlarge\"]\n    - key: \"topology.kubernetes.io/zone\" # If not included, all zones are considered\n      operator: In\n      values: [\"<span class=\"token variable\">${AWS_DEFAULT_REGION}</span>a\", \"<span class=\"token variable\">${AWS_DEFAULT_REGION}</span>b\"]\n    - key: \"karpenter.sh/capacity-type\"\n      operator: In\n      values: [\"spot\"]\n  labels: # Kubernetes labels\n    managed-by: karpenter\n  provider:\n    instanceProfile: KarpenterNodeInstanceProfile-<span class=\"token variable\">${CLUSTER_NAME}</span>\n    tags: # AWS EC2 Tags\n      managed-by: karpenter\n  ttlSecondsAfterEmpty: 30 # If a node is empty of non daemonset pods for this ttl, it is removed\nEOF</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>This one is quite similar to the first Provisioner, but we're using spot instances instead of on-demand, c5 type nodes, and no taint.</p>\n<p>Now that we have our provisioners defined, let's install Karpenter using Helm.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"79643157060565570000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`helm repo add karpenter https://charts.karpenter.sh\nhelm repo update\nhelm install karpenter \\\n    -n karpenter \\\n    --create-namespace \\\n    --version 0.5.2 \\\n    --set serviceAccount.annotations.eks\\\\.amazonaws\\\\.com/role-arn=\\$(terraform output -raw iam_role_arn) \\\n    --set controller.clusterName=\\${CLUSTER_NAME} \\\n    --set controller.clusterEndpoint=\\$(terraform output -raw cluster_endpoint) \\\n    --wait \\\n    karpenter/karpenter`, `79643157060565570000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">helm repo <span class=\"token function\">add</span> karpenter https://charts.karpenter.sh\nhelm repo update\nhelm <span class=\"token function\">install</span> karpenter <span class=\"token punctuation\">\\</span>\n    -n karpenter <span class=\"token punctuation\">\\</span>\n    --create-namespace <span class=\"token punctuation\">\\</span>\n    --version <span class=\"token number\">0.5</span>.2 <span class=\"token punctuation\">\\</span>\n    --set serviceAccount.annotations.eks<span class=\"token punctuation\">\\</span><span class=\"token punctuation\">\\</span>.amazonaws<span class=\"token punctuation\">\\</span><span class=\"token punctuation\">\\</span>.com/role-arn<span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span>terraform output -raw iam_role_arn<span class=\"token variable\">)</span></span> <span class=\"token punctuation\">\\</span>\n    --set controller.clusterName<span class=\"token operator\">=</span><span class=\"token variable\">${CLUSTER_NAME}</span> <span class=\"token punctuation\">\\</span>\n    --set controller.clusterEndpoint<span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span>terraform output -raw cluster_endpoint<span class=\"token variable\">)</span></span> <span class=\"token punctuation\">\\</span>\n    --wait <span class=\"token punctuation\">\\</span>\n    karpenter/karpenter</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Ok! We got almost everything we need to see this working, we're just missing one little thing, actual workloads :D</p>\n<p>You can apply the <code class=\"language-text\">workloads</code> folder from our git repository, we have two manifests there:</p>\n<ul>\n<li>addon.yaml - a deployment of a pause container, with a nodeSelector to the label <code class=\"language-text\">purpose: addons</code>, and tolerating the taint defined in the provisioner, with 1 replica</li>\n<li>general.yaml - a deployment of a pause container, with a nodeSelector to the label <code class=\"language-text\">managed-by: karpenter</code>, with 20 replicas</li>\n</ul>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"29640895187105886000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get pods -o=custom-columns=&quot;NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName&quot;\nNAME                               STATUS          MESSAGE                                                                         NODE\naddon-7fc784b5d-fg2dx              Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\ngeneral-workloads-5df49fcb-2hhqg   Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\ngeneral-workloads-5df49fcb-4mlqt   Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\ngeneral-workloads-5df49fcb-4zx4v   Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\ngeneral-workloads-5df49fcb-5788h   Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\ngeneral-workloads-5df49fcb-7b76r   Unschedulable   0/1 nodes are available: 1 node(s) didn't match Pod's node affinity/selector.   <none>\n...`, `29640895187105886000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get pods -o<span class=\"token operator\">=</span>custom-columns<span class=\"token operator\">=</span><span class=\"token string\">\"NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName\"</span>\nNAME                               STATUS          MESSAGE                                                                         NODE\naddon-7fc784b5d-fg2dx              Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-2hhqg   Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-4mlqt   Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-4zx4v   Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-5788h   Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-7b76r   Unschedulable   <span class=\"token number\">0</span>/1 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\n<span class=\"token punctuation\">..</span>.</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>With these deployed you can see that all 11 pods are pending, and their status says they're <code class=\"language-text\">Unschedulable</code>, the one node we have in the cluster does not match their constraints (nodeSelector), and that they have no node assigned.</p>\n<p>Let's check the status of our nodes:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"39783154700771650000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get nodes\nNAME                                          STATUS   ROLES    AGE     VERSION\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <none>   46h     v1.21.5-eks-bc4871b\n\nkubectl describe node ip-10-0-1-47.ca-central-1.compute.internal\nName:               ip-10-0-1-47.ca-central-1.compute.internal\nRoles:              <none>\nLabels:             beta.kubernetes.io/arch=amd64\n                    beta.kubernetes.io/instance-type=m5.large\n                    beta.kubernetes.io/os=linux\n                    failure-domain.beta.kubernetes.io/region=ca-central-1\n                    failure-domain.beta.kubernetes.io/zone=ca-central-1a\n                    kubernetes.io/arch=amd64\n                    kubernetes.io/hostname=ip-10-0-1-47.ca-central-1.compute.internal\n                    kubernetes.io/os=linux\n                    node.kubernetes.io/instance-type=m5.large\n                    topology.kubernetes.io/region=ca-central-1\n                    topology.kubernetes.io/zone=ca-central-1a\n...`, `39783154700771650000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get nodes\nNAME                                          STATUS   ROLES    AGE     VERSION\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   46h     v1.21.5-eks-bc4871b\n\nkubectl describe <span class=\"token function\">node</span> ip-10-0-1-47.ca-central-1.compute.internal\nName:               ip-10-0-1-47.ca-central-1.compute.internal\nRoles:              <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\nLabels:             beta.kubernetes.io/arch<span class=\"token operator\">=</span>amd64\n                    beta.kubernetes.io/instance-type<span class=\"token operator\">=</span>m5.large\n                    beta.kubernetes.io/os<span class=\"token operator\">=</span>linux\n                    failure-domain.beta.kubernetes.io/region<span class=\"token operator\">=</span>ca-central-1\n                    failure-domain.beta.kubernetes.io/zone<span class=\"token operator\">=</span>ca-central-1a\n                    kubernetes.io/arch<span class=\"token operator\">=</span>amd64\n                    kubernetes.io/hostname<span class=\"token operator\">=</span>ip-10-0-1-47.ca-central-1.compute.internal\n                    kubernetes.io/os<span class=\"token operator\">=</span>linux\n                    node.kubernetes.io/instance-type<span class=\"token operator\">=</span>m5.large\n                    topology.kubernetes.io/region<span class=\"token operator\">=</span>ca-central-1\n                    topology.kubernetes.io/zone<span class=\"token operator\">=</span>ca-central-1a\n<span class=\"token punctuation\">..</span>.</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>The existing node indeed doesn't have the labels we're trying to use for our nodeSelector in any of our workloads.</p>\n<p>Now let's deploy our first provisioner <code class=\"language-text\">addons-ondemand</code>.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"56185992152159180000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl apply -f node_group_addons.yaml\nprovisioner.karpenter.sh/addons-ondemand created`, `56185992152159180000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl apply -f node_group_addons.yaml\nprovisioner.karpenter.sh/addons-ondemand created</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>If you're following the Karpenter controller logs you will see a node be provisioned and the pod bound to it immediately.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"42483812887076500000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl logs -n karpenter -l karpenter=controller -f\n2021-12-17T18:49:33.800Z        INFO    controller.provisioning Batched 1 pods in 1.000321584s  {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;addons-ondemand&quot;}\n2021-12-17T18:49:33.804Z        INFO    controller.provisioning Computed packing of 1 node(s) for 1 pod(s) with instance type option(s) [m5.large m5.2xlarge]   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;addons-ondemand&quot;}\n2021-12-17T18:49:36.061Z        INFO    controller.provisioning Launched instance: i-03ffbc75bd75a68e7, hostname: ip-10-0-1-114.ca-central-1.compute.internal, type: m5.large, zone: ca-central-1a, capacityType: on-demand     {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;addons-ondemand&quot;}\n2021-12-17T18:49:36.098Z        INFO    controller.provisioning Bound 1 pod(s) to node ip-10-0-1-114.ca-central-1.compute.internal      {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;addons-ondemand&quot;}`, `42483812887076500000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl logs -n karpenter -l <span class=\"token assign-left variable\">karpenter</span><span class=\"token operator\">=</span>controller -f\n<span class=\"token number\">2021</span>-12-17T18:49:33.800Z        INFO    controller.provisioning Batched <span class=\"token number\">1</span> pods <span class=\"token keyword\">in</span> <span class=\"token number\">1</span>.000321584s  <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"addons-ondemand\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T18:49:33.804Z        INFO    controller.provisioning Computed packing of <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> <span class=\"token number\">1</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> with instance <span class=\"token builtin class-name\">type</span> option<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">[</span>m5.large m5.2xlarge<span class=\"token punctuation\">]</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"addons-ondemand\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T18:49:36.061Z        INFO    controller.provisioning Launched instance: i-03ffbc75bd75a68e7, hostname: ip-10-0-1-114.ca-central-1.compute.internal, type: m5.large, zone: ca-central-1a, capacityType: on-demand     <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"addons-ondemand\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T18:49:36.098Z        INFO    controller.provisioning Bound <span class=\"token number\">1</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> to <span class=\"token function\">node</span> ip-10-0-1-114.ca-central-1.compute.internal      <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"addons-ondemand\"</span><span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>If you check our pods again, you will see that its scheduled to a node.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"88050615903301710000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get pods -o=custom-columns=&quot;NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName&quot;\nNAME                               STATUS          MESSAGE                                                                                                                                                  NODE\naddon-7fc784b5d-fg2dx              <none>          <none>                                                                                                                                                   ip-10-0-1-114.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-2hhqg   Unschedulable   0/2 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) had taint {myops.co.il/addons: }, that the pod didn't tolerate.   <none>\ngeneral-workloads-5df49fcb-4mlqt   Unschedulable   0/2 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) had taint {myops.co.il/addons: }, that the pod didn't tolerate.   <none>\ngeneral-workloads-5df49fcb-4zx4v   Unschedulable   0/2 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) had taint {myops.co.il/addons: }, that the pod didn't tolerate.   <none>\n...`, `88050615903301710000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get pods -o<span class=\"token operator\">=</span>custom-columns<span class=\"token operator\">=</span><span class=\"token string\">\"NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName\"</span>\nNAME                               STATUS          MESSAGE                                                                                                                                                  NODE\naddon-7fc784b5d-fg2dx              <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>          <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>                                                                                                                                                   ip-10-0-1-114.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-2hhqg   Unschedulable   <span class=\"token number\">0</span>/2 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector, <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> had taint <span class=\"token punctuation\">{</span>myops.co.il/addons: <span class=\"token punctuation\">}</span>, that the pod didn<span class=\"token string\">'t tolerate.   &lt;none>\ngeneral-workloads-5df49fcb-4mlqt   Unschedulable   0/2 nodes are available: 1 node(s) didn'</span>t match Pod<span class=\"token string\">'s node affinity/selector, 1 node(s) had taint {myops.co.il/addons: }, that the pod didn'</span>t tolerate.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\ngeneral-workloads-5df49fcb-4zx4v   Unschedulable   <span class=\"token number\">0</span>/2 nodes are available: <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> didn<span class=\"token string\">'t match Pod'</span>s <span class=\"token function\">node</span> affinity/selector, <span class=\"token number\">1</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> had taint <span class=\"token punctuation\">{</span>myops.co.il/addons: <span class=\"token punctuation\">}</span>, that the pod didn't tolerate.   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\n<span class=\"token punctuation\">..</span>.</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>You will also notice that our general workloads are still <code class=\"language-text\">Unschedulable</code>, but that the message says that now 2 nodes don't match, one doesn't match the selector, the other has a taint the workload doesn't tolerate.</p>\n<p>Let's see our nodes now.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"93438868346621800000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get nodes\nNAME                                          STATUS   ROLES    AGE   VERSION\nip-10-0-1-114.ca-central-1.compute.internal   Ready    <none>   11m   v1.21.5-eks-bc4871b\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <none>   46h   v1.21.5-eks-bc4871b`, `93438868346621800000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get nodes\nNAME                                          STATUS   ROLES    AGE   VERSION\nip-10-0-1-114.ca-central-1.compute.internal   Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   11m   v1.21.5-eks-bc4871b\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   46h   v1.21.5-eks-bc4871b</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span></span></pre></div>\n<p>There is our new node! Let's see what Karpenter got us.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"59452922196911810000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl describe node ip-10-0-1-114.ca-central-1.compute.internal\nName:               ip-10-0-1-114.ca-central-1.compute.internal\nRoles:              <none>\nLabels:             beta.kubernetes.io/arch=amd64\n                    beta.kubernetes.io/instance-type=m5.large\n                    beta.kubernetes.io/os=linux\n                    failure-domain.beta.kubernetes.io/region=ca-central-1\n                    failure-domain.beta.kubernetes.io/zone=ca-central-1a\n                    karpenter.sh/capacity-type=on-demand\n                    karpenter.sh/provisioner-name=addons-ondemand\n                    kubernetes.io/arch=amd64\n                    kubernetes.io/hostname=ip-10-0-1-114.ca-central-1.compute.internal\n                    kubernetes.io/os=linux\n                    managed-by=karpenter\n                    node.kubernetes.io/instance-type=m5.large\n                    purpose=addons\n                    topology.kubernetes.io/region=ca-central-1\n                    topology.kubernetes.io/zone=ca-central-1a\nAnnotations:        node.alpha.kubernetes.io/ttl: 0\n                    volumes.kubernetes.io/controller-managed-attach-detach: true\nCreationTimestamp:  Fri, 17 Dec 2021 11:49:36 -0700\nTaints:             myops.co.il/addons:NoSchedule\n...\nCapacity:\n  attachable-volumes-aws-ebs:  25\n  cpu:                         2\n  ephemeral-storage:           20959212Ki\n  hugepages-1Gi:               0\n  hugepages-2Mi:               0\n  memory:                      7934464Ki\n  pods:                        29\nAllocatable:\n  attachable-volumes-aws-ebs:  25\n  cpu:                         1930m\n  ephemeral-storage:           18242267924\n  hugepages-1Gi:               0\n  hugepages-2Mi:               0\n  memory:                      7244288Ki\n  pods:                        29\n...`, `59452922196911810000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl describe <span class=\"token function\">node</span> ip-10-0-1-114.ca-central-1.compute.internal\nName:               ip-10-0-1-114.ca-central-1.compute.internal\nRoles:              <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>\nLabels:             beta.kubernetes.io/arch<span class=\"token operator\">=</span>amd64\n                    beta.kubernetes.io/instance-type<span class=\"token operator\">=</span>m5.large\n                    beta.kubernetes.io/os<span class=\"token operator\">=</span>linux\n                    failure-domain.beta.kubernetes.io/region<span class=\"token operator\">=</span>ca-central-1\n                    failure-domain.beta.kubernetes.io/zone<span class=\"token operator\">=</span>ca-central-1a\n                    karpenter.sh/capacity-type<span class=\"token operator\">=</span>on-demand\n                    karpenter.sh/provisioner-name<span class=\"token operator\">=</span>addons-ondemand\n                    kubernetes.io/arch<span class=\"token operator\">=</span>amd64\n                    kubernetes.io/hostname<span class=\"token operator\">=</span>ip-10-0-1-114.ca-central-1.compute.internal\n                    kubernetes.io/os<span class=\"token operator\">=</span>linux\n                    managed-by<span class=\"token operator\">=</span>karpenter\n                    node.kubernetes.io/instance-type<span class=\"token operator\">=</span>m5.large\n                    <span class=\"token assign-left variable\">purpose</span><span class=\"token operator\">=</span>addons\n                    topology.kubernetes.io/region<span class=\"token operator\">=</span>ca-central-1\n                    topology.kubernetes.io/zone<span class=\"token operator\">=</span>ca-central-1a\nAnnotations:        node.alpha.kubernetes.io/ttl: <span class=\"token number\">0</span>\n                    volumes.kubernetes.io/controller-managed-attach-detach: <span class=\"token boolean\">true</span>\nCreationTimestamp:  Fri, <span class=\"token number\">17</span> Dec <span class=\"token number\">2021</span> <span class=\"token number\">11</span>:49:36 -0700\nTaints:             myops.co.il/addons:NoSchedule\n<span class=\"token punctuation\">..</span>.\nCapacity:\n  attachable-volumes-aws-ebs:  <span class=\"token number\">25</span>\n  cpu:                         <span class=\"token number\">2</span>\n  ephemeral-storage:           20959212Ki\n  hugepages-1Gi:               <span class=\"token number\">0</span>\n  hugepages-2Mi:               <span class=\"token number\">0</span>\n  memory:                      7934464Ki\n  pods:                        <span class=\"token number\">29</span>\nAllocatable:\n  attachable-volumes-aws-ebs:  <span class=\"token number\">25</span>\n  cpu:                         1930m\n  ephemeral-storage:           <span class=\"token number\">18242267924</span>\n  hugepages-1Gi:               <span class=\"token number\">0</span>\n  hugepages-2Mi:               <span class=\"token number\">0</span>\n  memory:                      7244288Ki\n  pods:                        <span class=\"token number\">29</span>\n<span class=\"token punctuation\">..</span>.</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Our addon requires 1 core and 100Mb of memory, it has a nodeSelector pointing to the label <code class=\"language-text\">purpose</code> with value <code class=\"language-text\">addons</code> and tolerates the <code class=\"language-text\">myops.co.il/addons</code> taint.</p>\n<p>Our Provisioner <code class=\"language-text\">addons-ondemand</code> matches all these conditions, and in its instance type options we have m5.large that can fit our pod (you can see that the node has 1930m allocatable, our pod needs 1000m). Since the request matches a Provisioner's settings, we got a node for the workload.</p>\n<p>What about our other pods? Well, let's get their Provisioner up!</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"13243309728580410000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl apply -f node_group_general_spot.yaml\nprovisioner.karpenter.sh/spot-general created`, `13243309728580410000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl apply -f node_group_general_spot.yaml\nprovisioner.karpenter.sh/spot-general created</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>Once we apply the Provisioner you will see in Karpenter's logs:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"26609945194553995000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`2021-12-17T21:53:22.009Z        INFO    controller.provisioning Waiting for unschedulable pods  {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:34.896Z        INFO    controller.provisioning Batched 20 pods in 1.410203663s {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:34.906Z        INFO    controller.provisioning Computed packing of 3 node(s) for 20 pod(s) with instance type option(s) [c5.2xlarge]   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-082db60871ae40c9d, hostname: ip-10-0-1-162.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1a, capacityType: spot        {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-03d7f3f1d4bffdea4, hostname: ip-10-0-2-46.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1b, capacityType: spot {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-09dc16d84a292604c, hostname: ip-10-0-2-169.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1b, capacityType: spot        {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.591Z        INFO    controller.provisioning Bound 7 pod(s) to node ip-10-0-1-162.ca-central-1.compute.internal      {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.666Z        INFO    controller.provisioning Bound 7 pod(s) to node ip-10-0-2-46.ca-central-1.compute.internal       {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}\n2021-12-17T21:53:38.830Z        INFO    controller.provisioning Bound 6 pod(s) to node ip-10-0-2-169.ca-central-1.compute.internal      {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;provisioner&quot;: &quot;spot-general&quot;}`, `26609945194553995000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\"><span class=\"token number\">2021</span>-12-17T21:53:22.009Z        INFO    controller.provisioning Waiting <span class=\"token keyword\">for</span> unschedulable pods  <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:34.896Z        INFO    controller.provisioning Batched <span class=\"token number\">20</span> pods <span class=\"token keyword\">in</span> <span class=\"token number\">1</span>.410203663s <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:34.906Z        INFO    controller.provisioning Computed packing of <span class=\"token number\">3</span> node<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> <span class=\"token number\">20</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> with instance <span class=\"token builtin class-name\">type</span> option<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">[</span>c5.2xlarge<span class=\"token punctuation\">]</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-082db60871ae40c9d, hostname: ip-10-0-1-162.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1a, capacityType: spot        <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-03d7f3f1d4bffdea4, hostname: ip-10-0-2-46.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1b, capacityType: spot <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.533Z        INFO    controller.provisioning Launched instance: i-09dc16d84a292604c, hostname: ip-10-0-2-169.ca-central-1.compute.internal, type: c5.2xlarge, zone: ca-central-1b, capacityType: spot        <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.591Z        INFO    controller.provisioning Bound <span class=\"token number\">7</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> to <span class=\"token function\">node</span> ip-10-0-1-162.ca-central-1.compute.internal      <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.666Z        INFO    controller.provisioning Bound <span class=\"token number\">7</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> to <span class=\"token function\">node</span> ip-10-0-2-46.ca-central-1.compute.internal       <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T21:53:38.830Z        INFO    controller.provisioning Bound <span class=\"token number\">6</span> pod<span class=\"token punctuation\">(</span>s<span class=\"token punctuation\">)</span> to <span class=\"token function\">node</span> ip-10-0-2-169.ca-central-1.compute.internal      <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"provisioner\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"spot-general\"</span><span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Our 20 pods were split in 3 nodes, we can confirm that they are all scheduled by retrying our previous command to check their status:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"56654571971947340000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get pods -o=custom-columns=&quot;NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName&quot;\nNAME                               STATUS   MESSAGE   NODE\naddon-7fc784b5d-fg2dx              <none>   <none>    ip-10-0-1-114.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-7f2mf   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-7rls5   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-9qs99   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-bqnvc   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-d775z   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-g5kdd   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-gxkn9   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-jhq85   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-jvnhl   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-nfhq5   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-qpkdb   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-scmdp   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-tgtct   <none>   <none>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-ts4pt   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-v6cql   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-wqhtl   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-xpw52   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-xzgkq   <none>   <none>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-z47dd   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-zpd6s   <none>   <none>    ip-10-0-2-46.ca-central-1.compute.internal`, `56654571971947340000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get pods -o<span class=\"token operator\">=</span>custom-columns<span class=\"token operator\">=</span><span class=\"token string\">\"NAME:.metadata.name,STATUS:.status.conditions[*].reason,MESSAGE:.status.conditions[*].message,NODE:.spec.nodeName\"</span>\nNAME                               STATUS   MESSAGE   NODE\naddon-7fc784b5d-fg2dx              <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-114.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-7f2mf   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-7rls5   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-9qs99   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-bqnvc   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-d775z   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-g5kdd   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-gxkn9   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-jhq85   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-jvnhl   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-nfhq5   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-qpkdb   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-scmdp   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-tgtct   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-1-162.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-ts4pt   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-v6cql   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-wqhtl   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-xpw52   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-xzgkq   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-169.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-z47dd   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal\ngeneral-workloads-5df49fcb-zpd6s   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>    ip-10-0-2-46.ca-central-1.compute.internal</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>We should now have 5 nodes, 1 original node from Terraform, 1 from our addons-ondemand provisioner, 3 from the spot-general provisioner.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"44937952147455420000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get nodes\nNAME                                          STATUS   ROLES    AGE     VERSION\nip-10-0-1-114.ca-central-1.compute.internal   Ready    <none>   3h7m    v1.21.5-eks-bc4871b\nip-10-0-1-162.ca-central-1.compute.internal   Ready    <none>   3m57s   v1.21.5-eks-bc4871b\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <none>   2d1h    v1.21.5-eks-bc4871b\nip-10-0-2-169.ca-central-1.compute.internal   Ready    <none>   3m57s   v1.21.5-eks-bc4871b\nip-10-0-2-46.ca-central-1.compute.internal    Ready    <none>   3m57s   v1.21.5-eks-bc4871b`, `44937952147455420000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get nodes\nNAME                                          STATUS   ROLES    AGE     VERSION\nip-10-0-1-114.ca-central-1.compute.internal   Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   3h7m    v1.21.5-eks-bc4871b\nip-10-0-1-162.ca-central-1.compute.internal   Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   3m57s   v1.21.5-eks-bc4871b\nip-10-0-1-47.ca-central-1.compute.internal    Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   2d1h    v1.21.5-eks-bc4871b\nip-10-0-2-169.ca-central-1.compute.internal   Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   3m57s   v1.21.5-eks-bc4871b\nip-10-0-2-46.ca-central-1.compute.internal    Ready    <span class=\"token operator\">&lt;</span>none<span class=\"token operator\">></span>   3m57s   v1.21.5-eks-bc4871b</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Let's dig a bit into our new nodes now, which instance types we have now?</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"39796966681487820000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl get nodes -l karpenter.sh/provisioner-name=spot-general -o jsonpath='{.items[*].metadata.labels.node\\.kubernetes\\.io\\/instance-type}'\nc5.2xlarge c5.2xlarge c5.2xlarge`, `39796966681487820000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl get nodes -l karpenter.sh/provisioner-name<span class=\"token operator\">=</span>spot-general -o <span class=\"token assign-left variable\">jsonpath</span><span class=\"token operator\">=</span><span class=\"token string\">'{.items[*].metadata.labels.node\\.kubernetes\\.io\\/instance-type}'</span>\nc5.2xlarge c5.2xlarge c5.2xlarge</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span></span></pre></div>\n<p>Our <code class=\"language-text\">general-workloads</code> deployment pods only differ from the <code class=\"language-text\">addon</code> deployment for their nodeSelector and the lack of toleration for the <code class=\"language-text\">myops.co.il/addons</code> taint. Their nodeSelector label is set to <code class=\"language-text\">managed-by: karpenter</code> which also matches the <code class=\"language-text\">addons-ondemand</code> provisioner, but without the taint they can only match with the new Provisioner.</p>\n<p>With the Provisioner matched, Karpenter now needs to decide which instance type to use between c5.large and c5.2xlarge. A c5.large has 2vCPUs and 4Gb of memory, so it should only be able to take one of our pods (2vCPUs should have ~1900m allocatable, we need 1000m per pod), this would require us to have one instance per pod, quite a lot of resource waste in there (almost half the instance would sit unused).</p>\n<p>Now a c5.2xlarge has 8vCPUs and 16Gb of memory, which should fit 7 of our pods in each instance (8vCPUs should have ~7900m allocatable). This matches what we're seeing, 3 nodes, 7 pods in 1 instance, 7 pods in another instance, 6 pods in the last instance, 20 pods scheduled in the best way allowed by our provisioner.</p>\n<h2>Cleanup</h2>\n<p>Thanks for coming to our TED TALK! errr, quick review of Karpenter.</p>\n<p>Now let's cleanup and see one more feature of Karpenter.</p>\n<p>In both our Provisioners we have a setting <code class=\"language-text\">ttlSecondsAfterEmpty: 30</code>, which means that if a node has no pods (other than DaemonSet pods) for more than 30 seconds, it will be terminated.</p>\n<p>We won't take their word for it, let's check it!</p>\n<p>Let's delete our deployments:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"74766441134348200000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`kubectl delete deployment general-workloads addon\ndeployment.apps &quot;general-workloads&quot; deleted\ndeployment.apps &quot;addon&quot; deleted`, `74766441134348200000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">kubectl delete deployment general-workloads addon\ndeployment.apps <span class=\"token string\">\"general-workloads\"</span> deleted\ndeployment.apps <span class=\"token string\">\"addon\"</span> deleted</code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span></span></pre></div>\n<p>In Karpenter's logs we can see the nodes getting a ttl and then being cordoned, drained and terminated.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"81218637033571710000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`2021-12-17T22:29:23.877Z        INFO    controller.node Added TTL to empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-162.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:23.932Z        INFO    controller.node Added TTL to empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-46.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:24.031Z        INFO    controller.node Added TTL to empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-169.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:24.239Z        INFO    controller.node Added TTL to empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-114.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:53.889Z        INFO    controller.node Triggering termination after 30s for empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-162.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:53.915Z        INFO    controller.termination  Cordoned node   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-162.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:53.948Z        INFO    controller.node Triggering termination after 30s for empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-46.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:53.970Z        INFO    controller.termination  Cordoned node   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-46.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.042Z        INFO    controller.node Triggering termination after 30s for empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-169.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.068Z        INFO    controller.termination  Cordoned node   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-169.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.070Z        INFO    controller.termination  Deleted node    {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-162.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.147Z        INFO    controller.termination  Deleted node    {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-46.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.247Z        INFO    controller.termination  Deleted node    {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-2-169.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.261Z        INFO    controller.node Triggering termination after 30s for empty node {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-114.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.290Z        INFO    controller.termination  Cordoned node   {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-114.ca-central-1.compute.internal&quot;}\n2021-12-17T22:29:54.425Z        INFO    controller.termination  Deleted node    {&quot;commit&quot;: &quot;870e2f6&quot;, &quot;node&quot;: &quot;ip-10-0-1-114.ca-central-1.compute.internal&quot;}`, `81218637033571710000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\"><span class=\"token number\">2021</span>-12-17T22:29:23.877Z        INFO    controller.node Added TTL to empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-162.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:23.932Z        INFO    controller.node Added TTL to empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-46.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:24.031Z        INFO    controller.node Added TTL to empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-169.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:24.239Z        INFO    controller.node Added TTL to empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-114.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:53.889Z        INFO    controller.node Triggering termination after 30s <span class=\"token keyword\">for</span> empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-162.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:53.915Z        INFO    controller.termination  Cordoned <span class=\"token function\">node</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-162.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:53.948Z        INFO    controller.node Triggering termination after 30s <span class=\"token keyword\">for</span> empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-46.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:53.970Z        INFO    controller.termination  Cordoned <span class=\"token function\">node</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-46.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.042Z        INFO    controller.node Triggering termination after 30s <span class=\"token keyword\">for</span> empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-169.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.068Z        INFO    controller.termination  Cordoned <span class=\"token function\">node</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-169.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.070Z        INFO    controller.termination  Deleted <span class=\"token function\">node</span>    <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-162.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.147Z        INFO    controller.termination  Deleted <span class=\"token function\">node</span>    <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-46.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.247Z        INFO    controller.termination  Deleted <span class=\"token function\">node</span>    <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-2-169.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.261Z        INFO    controller.node Triggering termination after 30s <span class=\"token keyword\">for</span> empty <span class=\"token function\">node</span> <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-114.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.290Z        INFO    controller.termination  Cordoned <span class=\"token function\">node</span>   <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-114.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span>\n<span class=\"token number\">2021</span>-12-17T22:29:54.425Z        INFO    controller.termination  Deleted <span class=\"token function\">node</span>    <span class=\"token punctuation\">{</span><span class=\"token string\">\"commit\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"870e2f6\"</span>, <span class=\"token string\">\"node\"</span><span class=\"token builtin class-name\">:</span> <span class=\"token string\">\"ip-10-0-1-114.ca-central-1.compute.internal\"</span><span class=\"token punctuation\">}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>Without workloads and nodes, we are left with our initial cluster, which Terraform will gladly destroy.</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"97694522635117720000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"Copied\"\n              data-toaster-duration=\"5000\"\n              onClick=\"copyToClipboard(`terraform destroy -var cluster_name=\\${CLUSTER_NAME} -var region=\\${AWS_DEFAULT_REGION}`, `97694522635117720000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                <svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-shell line-numbers\"><code class=\"language-shell\">terraform destroy -var <span class=\"token assign-left variable\">cluster_name</span><span class=\"token operator\">=</span><span class=\"token variable\">${CLUSTER_NAME}</span> -var <span class=\"token assign-left variable\">region</span><span class=\"token operator\">=</span><span class=\"token variable\">${AWS_DEFAULT_REGION}</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<h2>Conclusion</h2>\n<h3>Pros</h3>\n<p>This same demo in Cluster Autoscaler should be marginally slower (a couple minutes difference, which depending on your workloads might be crucial, or not), but at a larger scale (think several services with hundreds of pods each) this speed difference by itself is a major advantage.</p>\n<p>Depending on how you manage tenancy in your clusters, you could even have the Provisioner deployed as part of your application through a helm chart, or just have an easier time managing node groups in general.</p>\n<h3>Cons</h3>\n<p>Karpenter still doesn't have a mechanism for removing underutilized nodes if their workloads can fit elsewhere, which is a feature present in the Cluster Autoscaler. This could possibly be handled by <a href=\"https://github.com/kubernetes-sigs/descheduler\">Descheduler</a> but that can be a whole other blog post :)</p>\n<p>Cluster Autoscaler has been around for a good while, and is beyond battle tested, while Karpenter is relatively new and might be rough around the edges.</p>\n<p>Karpenter only works on AWS right now, it can be expanded for other cloud providers though.</p>\n<h2>Final Thoughts</h2>\n<p>Karpenter is extremely promising, and its pros will outweight the cons in most cases. It is not an all or nothing solution either, you can have it running in parallel to Cluster Autoscaler and have the best of both worlds.</p>\n<p>There is a lot we didn't cover in here about Karpenter, take a look at our Related Links section at the bottom for some documentation and videos on it.</p>\n<p>We are looking forward to how this tool develops going forward!</p>\n<h2>Related Links</h2>\n<ul>\n<li><a href=\"https://karpenter.sh\">Karpenter</a></li>\n<li><a href=\"https://www.youtube.com/watch?v=3QsVRHVdOnM\">Karpenter vs Cluster Autoscaler</a></li>\n<li>Karpenter Provisioner API Docs</li>\n<li><a href=\"https://karpenter.sh/preview/getting-started/\">Karpenter Getting Started with Terraform</a></li>\n<li><a href=\"https://www.youtube.com/watch?v=_FXRIKWJWUk\">Containers from the Couch on Karpenter</a></li>\n<li><a href=\"https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler\">Cluster Autoscaler</a></li>\n<li><a href=\"https://github.com/aws/karpenter\">Karpenter on GitHub</a></li>\n</ul>\n<br>\n<h2>Written by:</h2>\n<p><strong>Fernando Battistella, Principal Architect at MyOps</strong> - Fernando has over two decades of experience in IT, with the last six years architecting cloud-native solutions for companies of all sizes. Specialized in Kubernetes and the Cloud Native ecosystem, he has helped multiple organizations design, build, migrate, operate and train their teams in cloud-native technologies and platforms.</p>","frontmatter":{"url":"karpenter","seo":{"title":"Karpenter - A New Way to Manage Kubernetes Node Groups","description":"Learn about AWS' recently released Karpenter and how it will bring a more native approach to managing your cluster nodes.","canonical":null,"image":{"childImageSharp":{"fluid":{"aspectRatio":1.9083969465648856,"src":"/static/e0d4e328e64d982af16b722b7165263b/5d2c5/aws-karpenter.png","srcSet":"/static/e0d4e328e64d982af16b722b7165263b/002c1/aws-karpenter.png 250w,\n/static/e0d4e328e64d982af16b722b7165263b/53f65/aws-karpenter.png 500w,\n/static/e0d4e328e64d982af16b722b7165263b/5d2c5/aws-karpenter.png 1000w,\n/static/e0d4e328e64d982af16b722b7165263b/6050d/aws-karpenter.png 1200w","srcWebp":"/static/e0d4e328e64d982af16b722b7165263b/36ebb/aws-karpenter.webp","srcSetWebp":"/static/e0d4e328e64d982af16b722b7165263b/1d872/aws-karpenter.webp 250w,\n/static/e0d4e328e64d982af16b722b7165263b/4e6d4/aws-karpenter.webp 500w,\n/static/e0d4e328e64d982af16b722b7165263b/36ebb/aws-karpenter.webp 1000w,\n/static/e0d4e328e64d982af16b722b7165263b/9000d/aws-karpenter.webp 1200w","sizes":"(max-width: 1000px) 100vw, 1000px","maxHeight":523,"maxWidth":1000}}}},"title":"Karpenter - A New Way to Manage Kubernetes Node Groups","date":"2022-01-20T00:00:00.000Z","tags":["Kubernetes","AWS"],"author":{"name":"MyOps","photo":{"extension":"png","publicURL":"/static/3ff870573bc56665ee67e3cf3f5fc163/logo-small.png","childImageSharp":{"fluid":{"aspectRatio":0.8759124087591241,"src":"/static/3ff870573bc56665ee67e3cf3f5fc163/b460a/logo-small.png","srcSet":"/static/3ff870573bc56665ee67e3cf3f5fc163/d966b/logo-small.png 120w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/67196/logo-small.png 240w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/b460a/logo-small.png 480w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/eec14/logo-small.png 596w","srcWebp":"/static/3ff870573bc56665ee67e3cf3f5fc163/35871/logo-small.webp","srcSetWebp":"/static/3ff870573bc56665ee67e3cf3f5fc163/83552/logo-small.webp 120w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/2b5a3/logo-small.webp 240w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/35871/logo-small.webp 480w,\n/static/3ff870573bc56665ee67e3cf3f5fc163/c0cb3/logo-small.webp 596w","sizes":"(max-width: 480px) 100vw, 480px"}}}},"image":{"childImageSharp":{"fluid":{"aspectRatio":1.910828025477707,"src":"/static/e0d4e328e64d982af16b722b7165263b/aca38/aws-karpenter.png","srcSet":"/static/e0d4e328e64d982af16b722b7165263b/788e6/aws-karpenter.png 300w,\n/static/e0d4e328e64d982af16b722b7165263b/c2ae5/aws-karpenter.png 600w,\n/static/e0d4e328e64d982af16b722b7165263b/aca38/aws-karpenter.png 1200w","srcWebp":"/static/e0d4e328e64d982af16b722b7165263b/e7405/aws-karpenter.webp","srcSetWebp":"/static/e0d4e328e64d982af16b722b7165263b/4fec1/aws-karpenter.webp 300w,\n/static/e0d4e328e64d982af16b722b7165263b/483a3/aws-karpenter.webp 600w,\n/static/e0d4e328e64d982af16b722b7165263b/e7405/aws-karpenter.webp 1200w","sizes":"(max-width: 1200px) 100vw, 1200px"}}}}}},"pageContext":{"id":"9ce02a96-8fc7-5693-83c2-5a0a03082a39","categories":["Kubernetes","AWS"]}},"staticQueryHashes":["2022990323","639612397"]}