CINXE.COM
Architecting Kubernetes clusters — choosing the best autoscaling strategy
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Architecting Kubernetes clusters — choosing the best autoscaling strategy</title><meta name="description" content="Learn how to size your cluster nodes, configure the Horizontal and Cluster Autoscaler, and overprovision your cluster for faster pod scaling."><meta name="author" content="Learnk8s"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@learnk8s"><meta property="fb:app_id" content="398212777530104"><link rel="icon" href="https://static.learnk8s.io/42aedfb7aa4f77d9f4fccd385dc684df.ico"><link rel="icon" href="https://static.learnk8s.io/f7e5160d4744cf05c46161170b5c11c9.svg" type="image/svg+xml" sizes="any"><link rel="apple-touch-icon" href="https://static.learnk8s.io/fddc0853df06c9c0c0f9f79b96abc14d.png"><link rel="manifest" href="/manifest.webmanifest"><link rel="alternate" type="application/rss+xml" title="Subscribe to Learnk8s RSS" href="/rss.xml"><meta property="og:site_name" content="Learnk8s"><meta name="pocket-site-verification" content="1476398dfb5a771a94da9466e0bb43"><meta property="og:url" content="https://learnk8s.io/kubernetes-autoscaling-strategies"><meta property="og:type" content="website"><meta property="og:title" content="Architecting Kubernetes clusters — choosing the best autoscaling strategy"><meta property="og:image" content="https://static.learnk8s.io/eb5fc1f81e240848c01415a8f3b6d79b.png"><meta property="og:description" content="Learn how to size your cluster nodes, configure the Horizontal and Cluster Autoscaler, and overprovision your cluster for faster pod scaling."><link rel="canonical" href="https://learnk8s.io/kubernetes-autoscaling-strategies"><script type="application/ld+json">{"@context":"https://schema.org","@type":"NewsArticle","headline":"Architecting Kubernetes clusters — choosing the best autoscaling strategy","image":["https://static.learnk8s.io/eb5fc1f81e240848c01415a8f3b6d79b.png"],"author":{"@type":"Person","name":"Daniele Polencic"},"publisher":{"@id":"https://learnk8s.io/contact-us"},"datePublished":"2021-06-01","dateModified":"2021-06-01","mainEntityOfPage":{"@type":"SoftwareSourceCode","@id":"https://learnk8s.io/kubernetes-autoscaling-strategies"}}</script><script defer data-domain="learnk8s.io" src="https://plausible.io/js/script.js"></script><style>input[type=checkbox]:checked~.checked-reveal,input[type=radio]:checked~.checked-reveal{display:block}.pagination-icon{stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:.125rem;display:inline-block;width:.4rem} /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}strong{font-weight:bolder}code{font-family:monospace,monospace;font-size:1em}img{border-style:none}button,input{font-family:inherit;font-size:100%;line-height:1.15;margin:0;overflow:visible}button{-webkit-appearance:button;text-transform:none}button::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring{outline:1px dotted ButtonText}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}a,article,blockquote,body,code,div,footer,form,h1,h2,header,html,input[type=email],li,nav,ol,p,pre,section,ul{box-sizing:border-box}.gray{color:#777}.bg-light-gray{background-color:#eee}.bg-near-white{background-color:#f4f4f4}.white{color:#fff}.bg-white{background-color:#fff}.b--white{border-color:#fff}.black-90{color:rgba(0,0,0,.9)}.black-80{color:rgba(0,0,0,.8)}.b--black-70{border-color:rgba(0,0,0,.7)}.black-60{color:rgba(0,0,0,.6)}.black-50{color:rgba(0,0,0,.5)}.b--black-20{border-color:rgba(0,0,0,.2)}.bg-black-10{background-color:rgba(0,0,0,.1)}.white-80{color:hsla(0,0%,100%,.8)}.white-60{color:hsla(0,0%,100%,.6)}.b--white-60{border-color:hsla(0,0%,100%,.6)}.b--white-20{border-color:hsla(0,0%,100%,.2)}.dark-red{color:#e7040f}.bg-dark-red{background-color:#e7040f}.bg-yellow{background-color:gold}.bg-green{background-color:#19a974}.b--green{border-color:#19a974}.bg-light-green{background-color:#9eebcf}.b--blue{border-color:#357edd}.navy{color:#001b44}.b--navy{border-color:#001b44}.hover-sky:focus,.hover-sky:hover{color:#569ad1}.bg-sky{background-color:#569ad1}.bg-evian{background-color:#f7f9fc}.blue-1{color:#001c47}.brown-0{color:#3c2201}.b--azure-4{border-color:#02acff}.hover-bg-azure-7:focus,.hover-bg-azure-7:hover{background-color:#95dcff}.bg-azure-8{background-color:#c6ecff}.bg-transparent{background-color:transparent}.link{text-decoration:none}.link,.link:active,.link:focus,.link:hover,.link:link,.link:visited{transition:color .15s ease-in}.link:focus{outline:1px dotted currentColor}.aspect-ratio{height:0;position:relative}.aspect-ratio--4x3{padding-bottom:75%}.aspect-ratio--6x4{padding-bottom:66.6%}.aspect-ratio--1x1{padding-bottom:100%}.aspect-ratio--object{bottom:0;height:100%;left:0;position:absolute;right:0;top:0;width:100%;z-index:8}.ba{border-style:solid;border-width:1px}.bt{border-top-style:solid;border-top-width:1px}.bb{border-bottom-style:solid;border-bottom-width:1px}.bl{border-left-style:solid;border-left-width:1px}.bn{border-style:none;border-width:0}.br1{border-radius:.125rem}.br2{border-radius:.25rem}.br-100{border-radius:100%}.br--bottom{border-top-left-radius:0;border-top-right-radius:0}.br--top{border-bottom-right-radius:0}.br--right,.br--top{border-bottom-left-radius:0}.br--right{border-top-left-radius:0}.bw1{border-width:.125rem}.bw2{border-width:.25rem}.bw3{border-width:.5rem}.shadow-4{box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.bottom-1{bottom:1rem}.cf:after,.cf:before{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.dn{display:none}.db{display:block}.dib{display:inline-block}.flex{display:flex}.flex-auto{flex:1 1 auto;min-height:0;min-width:0}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-between{justify-content:space-between}.flex-shrink-0{flex-shrink:0}.i{font-style:italic}.fs-normal{font-style:normal}.b{font-weight:700}.h1{height:1rem}.h2{height:2rem}.min-h-100{min-height:100%}.center{margin-left:auto;margin-right:auto}.lh-copy{line-height:1.5}.mw2{max-width:2rem}.mw4{max-width:8rem}.mw5{max-width:16rem}.mw6{max-width:32rem}.mw7{max-width:48rem}.mw8{max-width:64rem}.w1{width:1rem}.w2{width:2rem}.w3{width:4rem}.w4{width:8rem}.w5{width:16rem}.w-20{width:20%}.w-40{width:40%}.w-60{width:60%}.w-100{width:100%}.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.pa0{padding:0}.pl0{padding-left:0}.pt0{padding-top:0}.pb0{padding-bottom:0}.mt0,.mv0{margin-top:0}.mv0{margin-bottom:0}.pa1{padding:.25rem}.pl1{padding-left:.25rem}.pb1,.pv1{padding-bottom:.25rem}.pv1{padding-top:.25rem}.ph1{padding-left:.25rem;padding-right:.25rem}.ml1{margin-left:.25rem}.mt1{margin-top:.25rem}.mb1,.mv1{margin-bottom:.25rem}.mv1{margin-top:.25rem}.pa2{padding:.5rem}.pl2{padding-left:.5rem}.pr2{padding-right:.5rem}.pt2{padding-top:.5rem}.pb2,.pv2{padding-bottom:.5rem}.pv2{padding-top:.5rem}.ph2{padding-left:.5rem;padding-right:.5rem}.ml2{margin-left:.5rem}.mr2{margin-right:.5rem}.mt2{margin-top:.5rem}.mb2,.mv2{margin-bottom:.5rem}.mv2{margin-top:.5rem}.mh2{margin-left:.5rem;margin-right:.5rem}.pa3{padding:1rem}.pl3{padding-left:1rem}.pt3{padding-top:1rem}.pb3,.pv3{padding-bottom:1rem}.pv3{padding-top:1rem}.ph3{padding-left:1rem;padding-right:1rem}.mt3{margin-top:1rem}.mb3,.mv3{margin-bottom:1rem}.mv3{margin-top:1rem}.pb4{padding-bottom:2rem}.ph4{padding-left:2rem;padding-right:2rem}.mt4{margin-top:2rem}.mb4,.mv4{margin-bottom:2rem}.mv4{margin-top:2rem}.pt5{padding-top:4rem}.underline{text-decoration:underline}.tr{text-align:right}.tc{text-align:center}.ttu{text-transform:uppercase}.f2{font-size:2.25rem}.f3{font-size:1.5rem}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.f7{font-size:.75rem}.measure{max-width:30em}.measure-wide{max-width:34em}.measure-narrow{max-width:20em}.v-mid{vertical-align:middle}.word-nowrap-even-on-whitespace{white-space:nowrap;word-break:keep-all}.o-0{opacity:0}.sans-serif{font-family:-apple-system,BlinkMacSystemFont,avenir next,avenir,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.code,code{font-family:Consolas,monaco,monospace}.input-reset{-webkit-appearance:none;-moz-appearance:none}.input-reset::-moz-focus-inner{border:0;padding:0}.underline-hover:focus,.underline-hover:hover{text-decoration:underline}.pointer:hover{cursor:pointer}img{max-width:100%}.list{list-style-type:none}.z-1{z-index:1}.z-999{z-index:999}.z-max{z-index:2147483647}.code-light-theme{-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;padding-bottom:2ch;padding-top:2ch;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.code-light-theme .token.important{font-weight:700}.code-light-theme .code{float:left;min-width:100%}.code-light-theme .highlight,.code-light-theme .standard{box-sizing:border-box;display:block;min-width:100%;padding-left:2ch;padding-right:2ch}@keyframes blinking{0%,to{color:transparent}50%{color:#fff}}@-moz-keyframes blinking{0%,to{color:transparent}50%{color:#fff}}@-webkit-keyframes blinking{0%,to{color:transparent}50%{color:#fff}}@-ms-keyframes blinking{0%,to{color:transparent}50%{color:#fff}}@-o-keyframes blinking{0%,to{color:transparent}50%{color:#fff}}.code-light-theme{background-color:#fdf6e3;color:#657b83}.code-light-theme ::-moz-selection,.code-light-theme::-moz-selection{background:#073642}.code-light-theme ::selection,.code-light-theme::selection{background:#073642}.code-light-theme .token.punctuation{color:#586e75}.code-light-theme .token.boolean,.code-light-theme .token.number{color:#268bd2}.code-light-theme .token.string{color:#2aa198}.code-light-theme .token.atrule{color:#859900}.code-light-theme .token.important{color:#cb4b16}.code-light-theme .highlight{background:#ffe6c3}@media screen and (min-width:32em){.db-ns{display:block}.flex-ns{display:flex}.items-center-ns{align-items:center}.justify-between-ns{justify-content:space-between}.mw4-ns{max-width:8rem}.w-34-ns{width:34%}.w-50-ns{width:50%}.w-60-ns{width:60%}.ph4-ns{padding-left:2rem;padding-right:2rem}.mt5-ns{margin-top:4rem}.mb5-ns{margin-bottom:4rem}.f1-ns{font-size:3rem}}@media screen and (min-width:64em){.bn-l{border-style:none;border-width:0}.dn-l{display:none}.flex-l{display:flex}.items-start-l{align-items:flex-start}.items-center-l{align-items:center}.justify-around-l{justify-content:space-around}.mw9-l{max-width:96rem}.mw-100-l{max-width:100%}.w-100-l{width:100%}.static-l{position:static}.sticky-l{position:sticky}.mv0-l{margin-bottom:0;margin-top:0}.pv2-l{padding-bottom:.5rem;padding-top:.5rem}.ml3-l{margin-left:1rem}.mb5-l,.mv5-l{margin-bottom:4rem}.mv5-l{margin-top:4rem}}@media screen and (max-width:64em){#main-menu .reveal{background-color:#001b44;display:none}#main-menu:target .reveal{display:inherit}}.hamburger-icon{background:#fff;border-radius:.2rem;display:inline-block;height:.213em;position:relative;width:1.625em}.hamburger-icon:after,.hamburger-icon:before{background:#fff;content:"";height:.213em;position:absolute;width:1.625em}.hamburger-icon:before{top:-.625em}.hamburger-icon:after{bottom:-.625em}.x-icon{display:inline-block;height:.213em;position:relative;width:1.625em}.x-icon:after,.x-icon:before{background:#fff;content:"";height:.213em;left:0;margin-top:-.106em;position:absolute;top:50%;width:1.625em}.x-icon:before{transform:rotate(45deg)}.x-icon:after{transform:rotate(-45deg)}.js-subscribe-popup{transform:translateX(-100%);transition:all .4s ease-in-out}.js-popup-opened{transform:translateX(0)}</style></head><body class="bg-near-white sans-serif" tabindex="0"><div class="cf w-100 mw9-l center bg-white"><div class="white sticky-l top-0 z-max"><nav id="main-menu" class="nav bg-sky flex items-center justify-between ph1 pv2"><a href="/" class="logo db w-40 mw2 mw4-ns ml3-l" title="Learnk8s logo"><div class="flex-ns justify-between-ns items-center-ns"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 62 61" fill="#FFF" class="w-100 w-34-ns min-h-100"><path d="M45.324 32.699a2.264 2.264 0 01-2.262-2.262 2.264 2.264 0 012.262-2.26 2.264 2.264 0 012.261 2.26 2.264 2.264 0 01-2.261 2.262"></path><path d="M45.324 25.35a5.08 5.08 0 00-4.285 2.351c-.734-1.782-1.462-3.82-2.016-5.37-2.044-5.722-3.46-9.445-5.325-10.71a5.07 5.07 0 00-3.638-1.535 5.088 5.088 0 00-5.087 5.088 5.08 5.08 0 002.35 4.285c-1.781.734-3.82 1.462-5.37 2.016-5.722 2.044-9.444 3.46-10.71 5.325a5.088 5.088 0 003.553 8.725 5.08 5.08 0 004.285-2.35c.734 1.781 1.463 3.82 2.017 5.37 2.044 5.721 3.46 9.444 5.325 10.71a5.088 5.088 0 008.725-3.553 5.08 5.08 0 00-2.351-4.285c1.782-.734 3.82-1.463 5.37-2.017 5.722-2.044 9.445-3.46 10.71-5.325a5.07 5.07 0 001.535-3.638 5.088 5.088 0 00-5.088-5.087M33.25 59.882a3.08 3.08 0 01-4.355 0L1.623 32.61a3.08 3.08 0 010-4.356L28.895.982a3.08 3.08 0 014.355 0l27.272 27.272a3.08 3.08 0 010 4.356L33.25 59.882z"></path><path d="M14.797 32.699a2.264 2.264 0 01-2.262-2.262 2.264 2.264 0 012.262-2.26 2.264 2.264 0 012.261 2.26 2.264 2.264 0 01-2.261 2.262M30.06 17.435a2.264 2.264 0 01-2.261-2.261 2.264 2.264 0 012.261-2.26 2.264 2.264 0 012.262 2.26 2.264 2.264 0 01-2.262 2.261M26.507 42.063a5.12 5.12 0 00-.73.901c-.735-1.782-1.464-3.82-2.017-5.37-2.044-5.722-3.46-9.444-5.325-10.71a5.124 5.124 0 00-.901-.731c1.781-.734 3.82-1.463 5.37-2.016 5.721-2.043 9.444-3.46 10.71-5.326.277-.27.521-.572.73-.9.735 1.781 1.463 3.82 2.017 5.37 2.044 5.722 3.46 9.445 5.325 10.71.27.277.573.521.9.73-1.78.735-3.819 1.464-5.37 2.017-5.72 2.044-9.443 3.46-10.71 5.325M30.06 43.44a2.264 2.264 0 012.262 2.261 2.264 2.264 0 01-2.262 2.261 2.264 2.264 0 01-2.261-2.26 2.264 2.264 0 012.261-2.262"></path></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 27" fill="#FFF" class="dn db-ns w-60-ns"><path d="M3.04 19.875a1.325 1.325 0 01-.329-.606 3.827 3.827 0 01-.1-.962V2.51l-2.352.405v15.772c0 1.248.305 2.167.911 2.756.606.59 1.634.902 3.084.935l.328-1.971a6.298 6.298 0 01-.935-.19 1.42 1.42 0 01-.607-.341M8.98 14.289c.051-.455.156-.902.316-1.34.16-.439.383-.825.67-1.163a3.38 3.38 0 011.05-.822c.412-.21.888-.315 1.428-.315.96 0 1.714.34 2.262 1.024.547.682.813 1.555.796 2.616H8.98zm3.489-5.637c-.758 0-1.5.143-2.224.429a5.45 5.45 0 00-1.922 1.29c-.556.573-1.002 1.293-1.34 2.16-.337.87-.505 1.883-.505 3.047 0 .994.13 1.908.391 2.743a5.826 5.826 0 001.201 2.16c.54.608 1.226 1.084 2.06 1.429.835.345 1.824.518 2.971.518.91 0 1.722-.084 2.439-.253.716-.168 1.217-.328 1.504-.48l-.328-1.972c-.288.135-.712.274-1.277.417-.565.144-1.26.215-2.085.215-1.466 0-2.545-.354-3.236-1.062-.691-.707-1.087-1.743-1.188-3.109h9c.015-.135.024-.282.024-.442v-.392c0-2.257-.472-3.938-1.415-5.043-.944-1.103-2.3-1.655-4.07-1.655M28.343 20.254a6.332 6.332 0 01-1.074.14c-.43.024-.922.037-1.48.037-.926 0-1.659-.164-2.198-.493-.54-.328-.81-.913-.81-1.756 0-.456.11-.822.33-1.1.219-.278.493-.497.821-.657.328-.16.69-.266 1.087-.316.396-.05.77-.076 1.125-.076.54 0 .999.03 1.378.088.379.06.652.132.821.215v3.918zm1.201-10.199c-.396-.447-.92-.793-1.568-1.037-.649-.245-1.445-.366-2.388-.366-.826 0-1.593.062-2.3.19-.708.126-1.213.256-1.517.391l.278 1.947c.287-.119.72-.232 1.302-.342a11.16 11.16 0 012.035-.164c.607 0 1.1.088 1.478.265.38.177.679.413.898.708.219.296.37.632.455 1.011.084.38.126.762.126 1.15v.658a9.612 9.612 0 00-.354-.077 42.052 42.052 0 00-.593-.113 8.854 8.854 0 00-.721-.101 7.22 7.22 0 00-.733-.037 9.62 9.62 0 00-2.124.226 5.582 5.582 0 00-1.77.709c-.505.32-.905.741-1.2 1.263-.295.523-.442 1.146-.442 1.87 0 .759.127 1.408.38 1.947.252.54.606.974 1.06 1.302.455.329.995.568 1.618.72a8.681 8.681 0 002.048.228c.522 0 1.049-.021 1.58-.063.53-.042 1.024-.089 1.479-.14.454-.05.862-.104 1.226-.163.362-.06.644-.105.847-.14v-8.215c0-.741-.085-1.42-.253-2.035a3.925 3.925 0 00-.847-1.592M40.856 8.841a11.56 11.56 0 00-.772-.1 7.155 7.155 0 00-.695-.039c-1.028 0-1.954.088-2.78.266-.827.177-1.517.366-2.073.569v12.587h2.35V11.078c.136-.033.418-.097.847-.189.43-.092.864-.14 1.302-.14.674 0 1.226.048 1.656.14.43.092.736.173.923.24l.404-2.048a4.38 4.38 0 00-.468-.113 25.081 25.081 0 00-.694-.127M53.785 10.383c-.414-.53-.965-.944-1.656-1.238-.69-.295-1.558-.442-2.604-.442-1.162 0-2.19.075-3.084.227-.893.152-1.609.295-2.148.43v12.765h2.35V11.027c.085-.015.224-.041.418-.074.193-.034.412-.064.657-.09.244-.025.501-.046.771-.062.269-.018.531-.025.783-.025.624 0 1.146.079 1.568.239.421.16.758.417 1.011.77.253.354.433.82.543 1.39.11.574.165 1.265.165 2.074v6.876h2.35v-7.382c0-.892-.084-1.71-.252-2.451-.168-.742-.46-1.378-.872-1.909M68.711 18.25a39.621 39.621 0 00-1.568-1.962 17.506 17.506 0 00-1.566-1.633 73.593 73.593 0 002.793-2.888c.85-.933 1.722-1.912 2.616-2.938h-4.478c-.236.285-.518.62-.846 1.005-.329.385-.678.791-1.049 1.219-.37.427-.753.859-1.148 1.293-.396.437-.779.856-1.149 1.257V2.51l-3.767.606v19.009h3.767v-5.828c.42.339.845.752 1.273 1.242.43.489.837 1 1.225 1.532a36.3 36.3 0 011.097 1.597c.345.532.651 1.018.92 1.457h4.332a28.896 28.896 0 00-2.452-3.874M80.516 18.812c-.404.423-1.046.634-1.922.634-.454 0-.842-.068-1.163-.203a2.434 2.434 0 01-.783-.507 1.914 1.914 0 01-.443-.67 1.928 1.928 0 01-.138-.673c0-.66.16-1.225.48-1.698.32-.473.717-.887 1.188-1.242.472.151.914.317 1.327.495.413.177.771.38 1.075.607.302.228.542.495.72.799.177.303.265.65.265 1.039 0 .523-.202.996-.606 1.419M76.573 8.497a1.93 1.93 0 01.391-.617c.176-.194.4-.35.67-.468.269-.117.59-.176.96-.176.387 0 .717.063.987.19.268.125.493.282.67.465.177.186.303.383.379.593.075.21.113.407.113.592 0 .64-.142 1.176-.43 1.614-.287.437-.699.823-1.238 1.16-.961-.337-1.64-.74-2.035-1.211-.396-.47-.594-.974-.594-1.512 0-.202.041-.411.127-.63m5.56 4.389c.641-.404 1.175-.955 1.606-1.654.43-.698.644-1.45.644-2.259 0-.556-.106-1.115-.316-1.678a4.105 4.105 0 00-1.024-1.527c-.471-.454-1.074-.828-1.807-1.123-.734-.294-1.614-.442-2.642-.442-.876 0-1.672.14-2.389.417a5.767 5.767 0 00-1.832 1.11 4.878 4.878 0 00-1.175 1.628 4.709 4.709 0 00-.418 1.944c0 .891.173 1.624.518 2.196.346.572.881 1.153 1.606 1.742a9.83 9.83 0 00-.948.81c-.295.286-.56.603-.797.948-.236.347-.42.73-.556 1.152a4.563 4.563 0 00-.202 1.393c0 .49.1 1.025.305 1.607a4.305 4.305 0 001.023 1.607c.48.49 1.112.9 1.895 1.228.784.329 1.765.494 2.945.494 1.028 0 1.933-.132 2.718-.393.783-.26 1.436-.628 1.958-1.101a4.56 4.56 0 001.176-1.657c.261-.634.392-1.33.392-2.089 0-.91-.206-1.708-.62-2.392-.413-.683-1.098-1.337-2.06-1.961M96.807 17.03a2.976 2.976 0 00-.657-1.147c-.312-.344-.737-.666-1.277-.962-.54-.297-1.222-.6-2.047-.906a11.68 11.68 0 01-.998-.42 4.127 4.127 0 01-.62-.356.858.858 0 01-.303-.34 1.028 1.028 0 01-.076-.405c0-.657.59-.986 1.77-.986.64 0 1.216.06 1.732.177.513.118.989.253 1.427.405l.657-2.933c-.438-.168-1.028-.324-1.77-.467a12.262 12.262 0 00-2.324-.215c-1.618 0-2.89.362-3.818 1.087-.926.725-1.39 1.71-1.39 2.957 0 .641.092 1.188.278 1.644.186.454.447.846.783 1.175.338.328.747.61 1.227.846.48.237 1.015.465 1.605.683.759.286 1.322.544 1.694.77.37.228.556.493.556.797 0 .388-.143.65-.43.784-.287.135-.775.202-1.467.202a9.55 9.55 0 01-1.996-.215 12.298 12.298 0 01-1.972-.594l-.632 3.058c.303.136.848.304 1.63.506.784.203 1.766.304 2.945.304 1.804 0 3.199-.337 4.184-1.01.986-.672 1.479-1.664 1.479-2.975a5.1 5.1 0 00-.19-1.463"></path></svg></div></a><div class="relative"><a href="#main-menu" class="db h2 dn-l" title="Open menu"><span class="hamburger-icon"></span></a><a href="#" class="z-max reveal pt2 pr2 tc white absolute top-0 right-0 dn-l"><span class="x-icon"></span></a><ul class="z-999 reveal w5 list pl0 mv0 flex-l items-center-l absolute top-0 right-0 z-1 static-l w-100-l"><li class="ttu mh2 bb bn-l b--white"><a href="/corporate-training" class="white link db b ph1 pv3 pv2-l f5 underline-hover" title="Corporate instructor-led training">Corporate training</a></li><li class="ttu mh2 bb bn-l b--white"><a href="/training" class="white link db b ph1 pv3 pv2-l f5 underline-hover" title="Public instructor-led workshops">Public workshops</a></li><li class="ttu mh2 bb bn-l b--white"><a href="/blog" class="white link db b ph1 pv3 pv2-l f5 underline-hover" title="Blog">Blog</a></li><li class="ttu mh2"><a href="/contact-us" class="white link db b ph1 pv3 pv2-l f5 underline-hover" title="A curated list of Kubernetes resources and tools">Contact us</a></li></ul></div></nav></div><div class="tc mb4 db mw4 center mt4 mt5-ns"><div><a href="https://linkedin.com/in/danielepolencic" title="Daniele Polencic" class="link"><div class="center w3 mb1"><div class="aspect-ratio aspect-ratio--1x1"><img src="https://learnk8s.io/a/87a8c9a115f1827b77518e2bcf337f01.jpg" srcset="/a/87a8c9a115f1827b77518e2bcf337f01.jpg 1x, /a/456e9790cf86f2522dd4d0e70b139db2.jpg 2x" alt="Daniele Polencic" class="br-100 w3 dib aspect-ratio--object"></div></div><span class="black-50 f6 db">Daniele Polencic</span></a></div></div><article class="lazy-article ph3 pt0 pb4 mw7 center"><h1 class="navy tc f2 f1-ns">Architecting Kubernetes clusters — choosing the best autoscaling strategy</h1><p class="f7 black-60 tc ttu b">June 2021</p><hr class="pv2 bn"><div class="aspect-ratio aspect-ratio--6x4"><img src="https://static.learnk8s.io/0498c77a1b646af0f3fc42a03f0171fb.svg" class="aspect-ratio--object" alt="Architecting Kubernetes clusters — choosing the best autoscaling strategy"></div><hr class="w3 center b--navy mv4 mb5-ns"><p class="lh-copy measure-wide f4"><em class="i">TL;DR: Scaling pods and nodes in a Kubernetes cluster could take several minutes with the default settings. Learn how to size your cluster nodes, configure the Horizontal and Cluster Autoscaler, and overprovision your cluster for faster scaling.</em></p><p class="lh-copy measure-wide f4"><strong class="b">Table of content:</strong></p><ul><li class="lh-copy f4 mv1 measure-wide"><a href="#when-autoscaling-pods-goes-wrong" target="_self" class="link navy underline hover-sky">When autoscaling pods goes wrong</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#how-the-cluster-autoscaler-works-in-kubernetes" target="_self" class="link navy underline hover-sky">How the Cluster Autoscaler works in Kubernetes</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#exploring-pod-autoscaling-lead-time" target="_self" class="link navy underline hover-sky">Exploring pod autoscaling lead time</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#choosing-the-optimal-instance-size-for-a-kubernetes-node" target="_self" class="link navy underline hover-sky">Choosing the optimal instance size for a Kubernetes node</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#overprovisioning-nodes-in-your-kubernetes-cluster" target="_self" class="link navy underline hover-sky">Overprovisioning nodes in your Kubernetes cluster</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#selecting-the-correct-memory-and-cpu-requests-for-your-pods" target="_self" class="link navy underline hover-sky">Selecting the correct memory and CPU requests for your Pods</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#what-about-downscaling-a-cluster-" target="_self" class="link navy underline hover-sky">What about downscaling a cluster?</a></li><li class="lh-copy f4 mv1 measure-wide"><a href="#why-not-autoscaling-based-on-memory-or-cpu-" target="_self" class="link navy underline hover-sky">Why not autoscaling based on memory or CPU?</a></li></ul><p class="lh-copy measure-wide f4">In Kubernetes, several things are referred to as "autoscaling", including:</p><ul><li class="lh-copy f4 mv1 measure-wide"><a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Horizontal Pod Autoscaler</a>.</li><li class="lh-copy f4 mv1 measure-wide"><a href="https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Vertical Pod Autoscaler</a>.</li><li class="lh-copy f4 mv1 measure-wide"><a href="https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Cluster Autoscaler</a>.</li></ul><p class="lh-copy measure-wide f4">Those autoscalers belong to different categories because they address other concerns.</p><p class="lh-copy measure-wide f4">The <strong class="b">Horizontal Pod Autoscaler (HPA)</strong> is designed to increase the replicas in your deployments.</p><p class="lh-copy measure-wide f4">As your application receives more traffic, you could have the autoscaler adjusting the number of replicas to handle more requests.</p><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-1" id="carousel-1-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/b39ab8cff1b9a9f443aa9ef798c9dffb.svg" alt="The Horizontal Pod Autoscaler (HPA) inspects metrics such as memory and CPU at a regular interval." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">The Horizontal Pod Autoscaler (HPA) inspects metrics such as memory and CPU at a regular interval.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-1-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-1" id="carousel-1-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/e7f644e09b8c910ed4188be75b0fb54c.svg" alt="If the metrics pass a user-defined threshold, the autoscaler creates more Pods." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-1-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">If the metrics pass a user-defined threshold, the autoscaler creates more Pods.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4">The <strong class="b">Vertical Pod Autoscaler (VPA)</strong> is useful when you can't create more copies of your Pods, but you still need to handle more traffic.</p><p class="lh-copy measure-wide f4">As an example, you can't scale a database (easily) only by adding more Pods.</p><p class="lh-copy measure-wide f4">A database might require sharding or configuring read-only replicas.</p><p class="lh-copy measure-wide f4">But you can make a database handle more connections by increasing the memory and CPU available to it.</p><p class="lh-copy measure-wide f4">That's precisely the purpose of the vertical autoscaler — increasing the size of the Pod.</p><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-2" id="carousel-2-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/41e2f5317f5dc17ddd0fcb9846ceeae1.svg" alt="You can't only increase the number of replicas to scale a database in Kubernetes." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">You can't only increase the number of replicas to scale a database in Kubernetes.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-2-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-2" id="carousel-2-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/30a40e0b0de545f905f2f81ba5b5f264.svg" alt="But you can create a pod that has bigger resources assigned to it. The Vertical Pod Autoscaler can do that automatically." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-2-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">But you can create a pod that has bigger resources assigned to it. The Vertical Pod Autoscaler can do that automatically.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4">Lastly, the <strong class="b">Cluster Autoscaler (CA)</strong>.</p><p class="lh-copy measure-wide f4">When your cluster runs low on resources, the Cluster Autoscaler provision a new compute unit and adds it to the cluster.</p><p class="lh-copy measure-wide f4">If there are too many empty nodes, the cluster autoscaler will remove them to reduce costs.</p><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-3" id="carousel-3-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/7389f3827b5ba289475c2f03893b0d9e.svg" alt="When you scale your pods in Kubernetes, you might run out of space." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">When you scale your pods in Kubernetes, you might run out of space.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-3-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-3" id="carousel-3-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/538e5cb61b289fe230ba6753bf02141c.svg" alt="The Cluster Autoscaler is designed to increase the node count in your cluster." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-3-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">The Cluster Autoscaler is designed to increase the node count in your cluster.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-3-2">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-3" id="carousel-3-2" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/56f2b50284c4c0fba1e365356479dce8.svg" alt="You can keep scaling your pods without worrying about the underlying nodes. The cluster autoscaler will create more automatically." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">3</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-3-1"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">You can keep scaling your pods without worrying about the underlying nodes. The cluster autoscaler will create more automatically.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4">While these components all "autoscale" something, they are entirely unrelated to each other.</p><p class="lh-copy measure-wide f4">They all address very different use cases and use other concepts and mechanisms.</p><p class="lh-copy measure-wide f4">And they are developed in separate projects and can be used independently from each other.</p><p class="lh-copy measure-wide f4"><strong class="b">However, scaling your cluster requires fine-tuning the setting of the autoscalers so that they work in concert.</strong></p><p class="lh-copy measure-wide f4">Let's have a look at an example.</p><h2 class="f2 pt5 pb2 mt3" id="when-autoscaling-pods-goes-wrong">When autoscaling pods goes wrong</h2><p class="lh-copy measure-wide f4">Imagine having an application that requires and uses 1.5GB of memory and 0.25 vCPU at all times.</p><p class="lh-copy measure-wide f4">You provisioned a cluster with a single node of 8GB and 2 vCPU — it should be able to fit four pods perfectly (and have a little bit of extra space left).</p><img class="db pv3 center" src="https://learnk8s.io/a/458f663479dc10d60ba31648fbb225fb.svg" alt="A single node cluster with 8GB of memory and 2 vCPU" loading="lazy"><p class="lh-copy measure-wide f4">You deploy a single Pod and set up:</p><ol><li class="lh-copy f4 mv1 measure-wide">An <strong class="b">Horizontal Pod Autoscaler</strong> adds a replica every 10 incoming requests (i.e. if you have 40 concurrent requests, it should scale to 4 replicas).</li><li class="lh-copy f4 mv1 measure-wide">A <strong class="b">Cluster Autoscaler</strong> to create more nodes when resources are low.</li></ol><blockquote class="pl3 mh2 bl bw2 b--blue bg-evian pv1 ph4"><p class="lh-copy measure-wide f4">The Horizontal Pod Autoscaler can scale the replicas in your deployment using Custom Metrics such as the queries per second (QPS) from an Ingress controller.</p></blockquote><p class="lh-copy measure-wide f4">You start driving traffic 30 concurrent requests to your cluster and observe the following:</p><ol><li class="lh-copy f4 mv1 measure-wide">The <strong class="b">Horizontal Pod Autoscaler</strong> starts scaling the Pods.</li><li class="lh-copy f4 mv1 measure-wide">Two more Pods are created.</li><li class="lh-copy f4 mv1 measure-wide">The <strong class="b">Cluster Autoscaler</strong> doesn't trigger — no new node is created in the cluster.</li></ol><p class="lh-copy measure-wide f4">It makes sense since there's enough space for one more Pod in that node.</p><img class="db pv3 center" src="https://learnk8s.io/a/2af2246616bdd048e4ef698bb4c9648c.svg" alt="Scaling three replicas in a single node" loading="lazy"><p class="lh-copy measure-wide f4">You further increase the traffic to 40 concurrent requests and observe again:</p><ol><li class="lh-copy f4 mv1 measure-wide">The <strong class="b">Horizontal Pod Autoscaler</strong> creates one more Pod.</li><li class="lh-copy f4 mv1 measure-wide">The Pod is pending and cannot be deployed.</li><li class="lh-copy f4 mv1 measure-wide">The <strong class="b">Cluster Autoscaler</strong> triggers creating a new node.</li><li class="lh-copy f4 mv1 measure-wide">The node is provisioned in 4 minutes. After that, the pending Pod is deployed.</li></ol><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-4" id="carousel-4-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/1ffab2618c899dd9652e55ea8c973404.svg" alt="When you scale to four replicas, the fourth replicas isn't deployed in the first node. Instead, it stays "Pending"." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">When you scale to four replicas, the fourth replicas isn't deployed in the first node. Instead, it stays <em class="i">"Pending"</em>.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-4-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-4" id="carousel-4-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/39d444ab5b1f52c9b8f65a240c67e4e7.svg" alt="The autoscaler creates a new node, and the pod is finally deployed." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/2</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-4-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">The autoscaler creates a new node, and the pod is finally deployed.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4"><em class="i">Why is the fourth Pod not deployed in the first node?</em></p><p class="lh-copy measure-wide f4">Pods deployed in your Kubernetes cluster consume resources such as memory, CPU and storage.</p><p class="lh-copy measure-wide f4">However, on the same node, <strong class="b">the operating system and the kubelet require memory and CPU too.</strong></p><p class="lh-copy measure-wide f4">In a Kubernetes worker node's memory and CPU are divided into:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Resources needed to run the operating system and system daemons</strong> such as SSH, systemd, etc.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Resources necessary to run Kubernetes agents</strong> such as the Kubelet, the container runtime, <a href="https://github.com/kubernetes/node-problem-detector" target="_blank" rel="noreferrer" class="link navy underline hover-sky">node problem detector</a>, etc.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Resources available to Pods.</strong></li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Resources reserved to the <a href="https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#eviction-thresholds" target="_blank" rel="noreferrer" class="link navy underline hover-sky">eviction threshold</a></strong>.</li></ol><img class="db pv3 center" src="https://learnk8s.io/a/bbaadb833f5689978cfdd0d2fcd9b7ac.svg" alt="Resources in a Kubernetes cluster are consumed by Pods, the operating system, kubelet and eviction threshold" loading="lazy"><p class="lh-copy measure-wide f4">As you can guess, <a href="https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#eviction-thresholds" target="_blank" rel="noreferrer" class="link navy underline hover-sky">all of those quotas are customisable</a>, but you need to account for them.</p><p class="lh-copy measure-wide f4">In an 8GB and 2 vCPU virtual machine, you can expect:</p><ul><li class="lh-copy f4 mv1 measure-wide">100MB of memory and 0.1 vCPU to be reserved for the operating system.</li><li class="lh-copy f4 mv1 measure-wide">1.8GB of memory and 0.07 vCPU to be reserved for the Kubelet.</li><li class="lh-copy f4 mv1 measure-wide">100MB of memory for the eviction threshold.</li></ul><p class="lh-copy measure-wide f4"><strong class="b">The remaining ~6GB of memory and 1.83 vCPU are usable by the Pods.</strong></p><p class="lh-copy measure-wide f4">If your cluster runs a DeamonSet such as kube-proxy, you should further reduce the available memory and CPU.</p><p class="lh-copy measure-wide f4">Considering kube-proxy has requests of 128MB and 0.1 vCPU, only ~5.9GB of memory and 1.73 vCPU are available to run Pods.</p><p class="lh-copy measure-wide f4">Running a CNI like Flannel and a log collector such as Fluentd will further reduce your resource footprint.</p><p class="lh-copy measure-wide f4">After accounting for all the extra resources, you have space left for only three pods.</p><div class="mv4 mv5-l"><header class="bg-light-gray flex pv2 pl1 br--top br2 relative"><div class="w1 h1 ml1 br-100 bg-dark-red"></div><div class="w1 h1 ml1 br-100 bg-green"></div><div class="w1 h1 ml1 br-100 bg-yellow"></div></header><pre class="code-light-theme relative overflow-auto mv0 br2 br--bottom"><code class="code lh-copy"><span class="standard">OS 100MB, 0.1 vCPU + Kubelet 1.8GB, 0.07 vCPU + Eviction threshold 100MB, 0 vCPU + Daemonsets 128MB, 0.1 vCPU + ====================================== Used 2.1GB, 0.27 vCPU ====================================== Available to Pods 5.9GB, 1.73 vCPU Pod requests 1.5GB, 0.25 vCPU ====================================== Total (4 Pods) 6GB, 1vCPU</span></code></pre></div><p class="lh-copy measure-wide f4">The fourth stays "Pending" unless it can be deployed on another node.</p><p class="lh-copy measure-wide f4"><em class="i">Since the Cluster Autoscaler knows that there's no space for a fourth Pod, why doesn't it provision a new node?</em></p><p class="lh-copy measure-wide f4"><em class="i">Why does it wait for the Pod to be pending before it triggers creating a node?</em></p><h2 class="f2 pt5 pb2 mt3" id="how-the-cluster-autoscaler-works-in-kubernetes">How the Cluster Autoscaler works in Kubernetes</h2><p class="lh-copy measure-wide f4"><strong class="b">The Cluster Autoscaler doesn't look at memory or CPU available when it triggers the autoscaling.</strong></p><p class="lh-copy measure-wide f4">Instead, the Cluster Autoscaler reacts to events and checks for any unschedulable Pods every 10 seconds.</p><p class="lh-copy measure-wide f4">A pod is unschedulable when the scheduler is unable to find a node that can accommodate it.</p><p class="lh-copy measure-wide f4">For example, when a Pod requests 1 vCPU but the cluster has only 0.5 vCPU available, the scheduler marks the Pod as unschedulable.</p><p class="lh-copy measure-wide f4"><strong class="b">That's when the Cluster Autoscaler initiates creating a new node.</strong></p><p class="lh-copy measure-wide f4">The Cluster Autoscaler scans the current cluster and <a href="https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-are-expanders" target="_blank" rel="noreferrer" class="link navy underline hover-sky">checks if any of the unschedulable pods would fit on in a new node.</a></p><p class="lh-copy measure-wide f4">If you have a cluster with several node types (often also referred to as node groups or node pools), the Cluster Autoscaler will pick one of them using the following strategies:</p><ul><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Random</strong> — picks a node type at random. This is the default strategy.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Most pods</strong> — selects the node group that would schedule the most pods.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Least waste</strong> — selects the node group with the least idle CPU after scale-up.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Price</strong> — select the node group that will cost the least (only works for GCP at the moment).</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Priority</strong> — selects the node group with the highest priority (and you manually assign priorities).</li></ul><p class="lh-copy measure-wide f4">Once the node type is identified, the Cluster Autoscaler will call the relevant API to provision a new compute resource.</p><p class="lh-copy measure-wide f4">If you're using AWS, the Cluster Autoscaler will provision a new EC2 instance.</p><p class="lh-copy measure-wide f4">On Azure, it will create a new Virtual Machine and on GCP, a new Compute Engine.</p><p class="lh-copy measure-wide f4">It may take some time before the created nodes appear in Kubernetes.</p><p class="lh-copy measure-wide f4">Once the compute resource is ready, the <a href="https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/" target="_blank" rel="noreferrer" class="link navy underline hover-sky">node is initialised</a> and added to the cluster where unscheduled Pods can be deployed.</p><p class="lh-copy measure-wide f4"><strong class="b">Unfortunately, provisioning new nodes is usually slow.</strong></p><p class="lh-copy measure-wide f4">It might take several minutes to provision a new compute unit.</p><p class="lh-copy measure-wide f4"><em class="i">But let's dive into the numbers.</em></p><h2 class="f2 pt5 pb2 mt3" id="exploring-pod-autoscaling-lead-time">Exploring pod autoscaling lead time</h2><p class="lh-copy measure-wide f4">The time it takes to create a new Pod on a new Node is determined by four major factors:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Horizontal Pod Autoscaler reaction time.</strong></li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Cluster Autoscaler reaction time.</strong></li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Node provisioning time.</strong></li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Pod creation time.</strong></li></ol><p class="lh-copy measure-wide f4">By default, <a href="https://github.com/kubernetes/kubernetes/blob/2da8d1c18fb9406bd8bb9a51da58d5f8108cb8f7/pkg/kubelet/kubelet.go#L1855" target="_blank" rel="noreferrer" class="link navy underline hover-sky">pods' CPU and memory usage is scraped by kubelet every 10 seconds.</a></p><p class="lh-copy measure-wide f4"><a href="https://github.com/kubernetes-sigs/metrics-server/blob/master/FAQ.md#how-often-metrics-are-scraped" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Every minute, the Metrics Server will aggregate those metrics</a> and expose them to the rest of the Kubernetes API.</p><p class="lh-copy measure-wide f4">The Horizontal Pod Autoscaler controller is in charge of checking the metrics and deciding to scale up or down your replicas.</p><p class="lh-copy measure-wide f4">By default, the <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#how-does-the-horizontal-pod-autoscaler-work" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Horizontal Pod Autoscaler checks Pods metrics every 15 seconds.</a></p><p class="lh-copy measure-wide f4">In the worst-case scenario, the Horizontal Pod Autoscaler can take up to 1 minute and a half to trigger the autoscaling (i.e. 10s + 60s + 15s).</p><img class="db pv3 center" src="https://learnk8s.io/a/f147f5a02119f3320d03c689397f3b48.svg" alt="The Horizontal Pod Autoscaler can take up to 1 minute and a half to trigger the autoscaling" loading="lazy"><p class="lh-copy measure-wide f4"><a href="https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#how-does-scale-up-work" target="_blank" rel="noreferrer" class="link navy underline hover-sky">The Cluster Autoscaler checks for unschedulable Pods in the cluster every 10 seconds.</a></p><p class="lh-copy measure-wide f4">Once one or more Pods are detected, it will run an algorithm to decide:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">How many nodes</strong> are necessary to deploy all pending Pods.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">What type of node group</strong> should be created.</li></ol><p class="lh-copy measure-wide f4">The entire process should take:</p><ul><li class="lh-copy f4 mv1 measure-wide"><strong class="b">No more than 30 seconds</strong> on clusters with <strong class="b">less than 100 nodes</strong> with up to 30 pods each. The average latency should be about 5 seconds.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">No more than 60 seconds</strong> on cluster with <strong class="b">100 to 1000 nodes</strong>. The average latency should be about 15 seconds.</li></ul><img class="db pv3 center" src="https://learnk8s.io/a/54ed073d5b8e6c852ba0a7cb19dedec0.svg" alt="The Cluster Autoscaler takes 30 seconds to decide to create a small node" loading="lazy"><p class="lh-copy measure-wide f4">Then, there's the Node provisioning time, which depends mainly on the cloud provider.</p><p class="lh-copy measure-wide f4"><strong class="b">It's pretty standard for a new compute resource to be provisioned in 3 to 5 minutes.</strong></p><img class="db pv3 center" src="https://learnk8s.io/a/fdaa1ad973d840c63de2430ae6efdab6.svg" alt="Creating a virtual machine on a cloud provider could take several minutes" loading="lazy"><p class="lh-copy measure-wide f4">Lastly, the Pod has to be created by the container runtime.</p><p class="lh-copy measure-wide f4">Launching a container shouldn't take more than few milliseconds, but <strong class="b">downloading the container image could take several seconds.</strong></p><p class="lh-copy measure-wide f4">If you're not caching your container images, downloading an image from the container registry could take from a couple of seconds up to a minute, depending on the size and number of layers.</p><img class="db pv3 center" src="https://learnk8s.io/a/8c0b05d9016ee14a1a6f9952c9d3aa8a.svg" alt="Downloading a container image could take time and affect scaling" loading="lazy"><p class="lh-copy measure-wide f4">So the total timing for trigger the autoscaling when there is no space in the current cluster is:</p><ol><li class="lh-copy f4 mv1 measure-wide">The Horizontal Pod Autoscaler might take up to 1m30s to increase the number of replicas.</li><li class="lh-copy f4 mv1 measure-wide">The Cluster Autoscaler should take less than 30 seconds for a cluster with less than 100 nodes and less than a minute for a cluster with more than 100 nodes.</li><li class="lh-copy f4 mv1 measure-wide">The cloud provider might take 3 to 5 minutes to create the computer resource.</li><li class="lh-copy f4 mv1 measure-wide">The container runtime could take up to 30 seconds to download the container image.</li></ol><p class="lh-copy measure-wide f4">In the worse case, with a small cluster, you have:</p><div class="mv4 mv5-l"><header class="bg-light-gray flex pv2 pl1 br--top br2 relative"><div class="w1 h1 ml1 br-100 bg-dark-red"></div><div class="w1 h1 ml1 br-100 bg-green"></div><div class="w1 h1 ml1 br-100 bg-yellow"></div></header><pre class="code-light-theme relative overflow-auto mv0 br2 br--bottom"><code class="code lh-copy"><span class="standard">HPA delay: 1m30s + CA delay: 0m30s + Cloud provider: 4m + Container runtime: 0m30s + ========================= Total 6m30s</span></code></pre></div><p class="lh-copy measure-wide f4">With a cluster with more than 100 nodes, the total delay could be up to 7 minutes.</p><p class="lh-copy measure-wide f4"><em class="i">Are you happy to wait for 7 minutes before you have more Pods to handle a sudden surge in traffic?</em></p><p class="lh-copy measure-wide f4"><em class="i">How can you tune the autoscaling to reduce the 7 minutes scaling time if you need a new node?</em></p><p class="lh-copy measure-wide f4">You could change:</p><ul><li class="lh-copy f4 mv1 measure-wide">The refresh time for the Horizontal Pod Autoscaler (controlled by the <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">--horizontal-pod-autoscaler-sync-period</code> flag, default is 15 seconds).</li><li class="lh-copy f4 mv1 measure-wide">The interval for metrics scraping in the Metrics Server (controlled by the <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">metric-resolution</code> flag, default 60 seconds).</li><li class="lh-copy f4 mv1 measure-wide">How frequently the cluster autoscaler scans for unscheduled Pods (controlled by the <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">scan-interval</code> flag, default 10 seconds).</li><li class="lh-copy f4 mv1 measure-wide">How you cache the image on the local node (<a href="https://github.com/senthilrch/kube-fledged" target="_blank" rel="noreferrer" class="link navy underline hover-sky">with a tool such as kube-fledged</a>).</li></ul><p class="lh-copy measure-wide f4">But even if you were to tune those settings to a tiny number, you will still be limited by the cloud provider provisioning time.</p><p class="lh-copy measure-wide f4"><em class="i">So, how could you fix that?</em></p><p class="lh-copy measure-wide f4">Since you can't change the provisioning time, you will need a workaround this time.</p><p class="lh-copy measure-wide f4">You could try two things:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Avoid creating new nodes,</strong> if possible.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Creating nodes proactively</strong> so that they are already provisioned when you need them.</li></ol><p class="lh-copy measure-wide f4"><em class="i">Let's have a look at the options one at a time.</em></p><h2 class="f2 pt5 pb2 mt3" id="choosing-the-optimal-instance-size-for-a-kubernetes-node">Choosing the optimal instance size for a Kubernetes node</h2><p class="lh-copy measure-wide f4"><strong class="b">Choosing the right instance type for your cluster has dramatic consequences on your scaling strategy.</strong></p><p class="lh-copy measure-wide f4"><em class="i">Consider the following scenario.</em></p><p class="lh-copy measure-wide f4">You have an application that requests 1GB of memory and 0.1 vCPU.</p><p class="lh-copy measure-wide f4">You provision a node that has 4GB of memory and 1 vCPU.</p><p class="lh-copy measure-wide f4">After reserving memory and CPU for the kubelet, operating system and eviction threshold, you are left with ~2.5GB of memory and 0.7 vCPU that can be used for running Pods.</p><img class="db pv3 center" src="https://learnk8s.io/a/22fe8bec231d15671512cf797ff3d1cc.svg" alt="Choosing a smaller instance can affect scaling" loading="lazy"><p class="lh-copy measure-wide f4">Your node has space for only two Pods.</p><p class="lh-copy measure-wide f4">Every time you scale your replicas, you are likely to incur in up to 7 minutes delay (the lead time to trigger the Horizontal Pod Autoscaler, Cluster Autoscaler and provisioning the compute resource on the cloud provider).</p><p class="lh-copy measure-wide f4"><em class="i">Let's have a look at what happens if you decide to use a 64GB memory and 16 vCPU node instead.</em></p><p class="lh-copy measure-wide f4">After reserving memory and CPU for the kubelet, operating system and eviction threshold, you are left with ~58.32GB of memory and 15.8 vCPU that can be used for running Pods.</p><p class="lh-copy measure-wide f4"><strong class="b">The available space can host 58 Pods, and you are likely to need a new node only when you have more than 58 replicas.</strong></p><img class="db pv3 center" src="https://learnk8s.io/a/691e6c33c3d1db3bb5906512552c5bac.svg" alt="Choosing a larger instance can affect scaling" loading="lazy"><p class="lh-copy measure-wide f4">Also, every time a node is added to the cluster, several pods can be deployed.</p><p class="lh-copy measure-wide f4">There is less chance to trigger <em class="i">again</em> the Cluster Autoscaler (and provisioning new compute units on the cloud provider).</p><p class="lh-copy measure-wide f4">Choosing large instance types also has another benefit.</p><p class="lh-copy measure-wide f4"><strong class="b">The ratio between resource reserved for Kubelet, operating system and eviction threshold and available resources to run Pods is greater.</strong></p><p class="lh-copy measure-wide f4">Have a look at this graph that pictures the memory available to pods.</p><img class="db pv3 center" src="https://learnk8s.io/a/6829f5509ca3044e1d3166a1f6218eac.svg" alt="Memory available to pods based on different instance types" loading="lazy"><p class="lh-copy measure-wide f4">As the instance size increase, you can notice that (in proportion) the resources available to pods increase.</p><p class="lh-copy measure-wide f4">In other words, you are utilising your resources more efficiently than having two instances of half of the size.</p><p class="lh-copy measure-wide f4"><em class="i">Should you select the biggest instance all the time?</em></p><p class="lh-copy measure-wide f4"><strong class="b">There's a peak in efficiency dictated by how many Pods you can have on the node.</strong></p><p class="lh-copy measure-wide f4">Some cloud providers limit the number of Pods to 110 (i.e. GKE). Others have limits dictated by the underlying network on a per-instance basis (i.e. AWS).</p><blockquote class="pl3 mh2 bl bw2 b--blue bg-evian pv1 ph4"><p class="lh-copy measure-wide f4"><a href="https://docs.google.com/spreadsheets/d/1RPpyDOLFmcgxMCpABDzrsBYWpPYCIBuvAoUQLwOGoQw/edit#gid=907731238" target="_blank" rel="noreferrer" class="link navy underline hover-sky">You can inspect the limits from most cloud providers here.</a></p></blockquote><p class="lh-copy measure-wide f4"><strong class="b">And choosing a larger instance type is not always a good option.</strong></p><p class="lh-copy measure-wide f4">You should also consider:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Blast radius</strong> — if you have only a few nodes, then the impact of a failing node is bigger than if you have many nodes.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Autoscaling is less cost-effective</strong> as the next increment is a (very) large node.</li></ol><p class="lh-copy measure-wide f4">Assuming you have selected the right instance type for your cluster, you might still face a delay in provisioning the new compute unit.</p><p class="lh-copy measure-wide f4"><em class="i">How can you work around that?</em></p><p class="lh-copy measure-wide f4"><em class="i">What if instead of creating a new node when it's time to scale, you create the same node ahead of time?</em></p><h2 class="f2 pt5 pb2 mt3" id="overprovisioning-nodes-in-your-kubernetes-cluster">Overprovisioning nodes in your Kubernetes cluster</h2><p class="lh-copy measure-wide f4">If you can afford to have a spare node available at all times, you could:</p><ol><li class="lh-copy f4 mv1 measure-wide">Create a node and leave it empty.</li><li class="lh-copy f4 mv1 measure-wide">As soon as there's a Pod in the empty node, you create another empty node.</li></ol><p class="lh-copy measure-wide f4"><strong class="b">In other words, you teach the autoscaler always to have a spare empty node if you need to scale.</strong></p><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-5" id="carousel-5-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/dfe3abd74845075ae2f9fc9b4cf896c3.svg" alt="When you decide to overprovision a cluster, a node is always empty and ready to deploy Pods." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">When you decide to overprovision a cluster, a node is always empty and ready to deploy Pods.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-5-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-5" id="carousel-5-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/3985a0a0d597984cde1d93cfcb52bbc0.svg" alt="As soon as a Pod is created in the empty node, the Cluster Autoscaler creates a new node." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-5-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">As soon as a Pod is created in the empty node, the Cluster Autoscaler creates a new node.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-5-2">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-5" id="carousel-5-2" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/47d04a1de379586d150bfb566a076277.svg" alt="Since creating the Node happens in the background, you will likely not notice the lead time to provision a cloud machine." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">3</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-5-1"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">Since creating the Node happens in the background, you will likely not notice the lead time to provision a cloud machine.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4"><strong class="b">It's a trade-off: you incur an extra cost (one empty compute unit available at all times), but you gain in speed.</strong></p><p class="lh-copy measure-wide f4">With this strategy, you can scale your fleet much quicker.</p><p class="lh-copy measure-wide f4"><em class="i">But there's bad and good news.</em></p><p class="lh-copy measure-wide f4">The bad news is that the Cluster Autoscaler doesn't have this functionality built-in.</p><p class="lh-copy measure-wide f4"><strong class="b">It cannot be configured to be proactive, and there is no flag to "always provision an empty node".</strong></p><p class="lh-copy measure-wide f4">The good news is that you can still fake it.</p><p class="lh-copy measure-wide f4"><em class="i">Let me explain.</em></p><p class="lh-copy measure-wide f4"><strong class="b">You could run a Deployment with enough requests to reserve an entire node.</strong></p><p class="lh-copy measure-wide f4">You could think about this pod as a placeholder — it is meant to reserve space, not use any resource.</p><p class="lh-copy measure-wide f4">As soon as a real Pod is created, you could evict the placeholder and deploy the Pod.</p><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-6" id="carousel-6-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/5297ee233777a99ef552f288299ffb80.svg" alt="In an overprovisioned cluster you have a Pod as a placeholder with low priority." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">In an overprovisioned cluster you have a Pod as a placeholder with low priority.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-6-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-6" id="carousel-6-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/d531de8c835b3c341de4ac98bcb4f06a.svg" alt="As soon as you create more replicas, the scheduler evicts the placeholder pod and deploys the new Pod. The placeholder pod is unschedulable and triggers the Cluster Autoscaler." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-6-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">As soon as you create more replicas, the scheduler evicts the placeholder pod and deploys the new Pod. The placeholder pod is unschedulable and triggers the Cluster Autoscaler.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-6-2">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-6" id="carousel-6-2" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/e43d719a023b91a8f407f51ad05e2325.svg" alt="In the background, the new node is provisioned and the placeholder pod is deployed into it." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">3</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-6-1"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">In the background, the new node is provisioned and the placeholder pod is deployed into it.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4">Notice how this time, you still have to wait 5 minutes for the node to be added to the cluster, but you can keep using the current node.</p><p class="lh-copy measure-wide f4">In the meantime, a new node is provisioned in the background.</p><p class="lh-copy measure-wide f4"><em class="i">How can you achieve that?</em></p><p class="lh-copy measure-wide f4"><strong class="b">Overprovisioning can be configured using deployment running a pod that sleeps forever.</strong></p><div class="mv4 mv5-l"><header class="bg-light-gray flex pv2 pl1 br--top br2 relative"><div class="w1 h1 ml1 br-100 bg-dark-red"></div><div class="w1 h1 ml1 br-100 bg-green"></div><div class="w1 h1 ml1 br-100 bg-yellow"></div><p class="code f6 mv0 black-60 w-100 tc absolute top-0 left-0 h1 pv2">overprovision.yaml</p></header><pre class="code-light-theme relative overflow-auto mv0 br2 br--bottom"><code class="code lh-copy"><span class="standard"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1 <span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment <span class="token key atrule">metadata</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">spec</span><span class="token punctuation">:</span> <span class="token key atrule">replicas</span><span class="token punctuation">:</span> <span class="token number">1</span> <span class="token key atrule">selector</span><span class="token punctuation">:</span> <span class="token key atrule">matchLabels</span><span class="token punctuation">:</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">template</span><span class="token punctuation">:</span> <span class="token key atrule">metadata</span><span class="token punctuation">:</span> <span class="token key atrule">labels</span><span class="token punctuation">:</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">spec</span><span class="token punctuation">:</span> <span class="token key atrule">containers</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> pause </span><span class="highlight"> <span class="token key atrule">image</span><span class="token punctuation">:</span> registry.k8s.io/pause </span><span class="standard"> <span class="token key atrule">resources</span><span class="token punctuation">:</span> </span><span class="highlight"> <span class="token key atrule">requests</span><span class="token punctuation">:</span> <span class="token key atrule">cpu</span><span class="token punctuation">:</span> <span class="token string">'1739m'</span> <span class="token key atrule">memory</span><span class="token punctuation">:</span> <span class="token string">'5.9G'</span></span></code></pre></div><p class="lh-copy measure-wide f4"><strong class="b">You should pay extra attention to the memory and CPU requests.</strong></p><p class="lh-copy measure-wide f4">The scheduler uses those values to decide where to deploy a Pod.</p><p class="lh-copy measure-wide f4">In this particular case, they are used to reserve the space.</p><p class="lh-copy measure-wide f4">You could provision a single large pod that has roughly the requests matching the available node resources.</p><p class="lh-copy measure-wide f4"><strong class="b">Please make sure that you account for resources consumed by the kubelet, operating system, kube-proxy, etc.</strong></p><p class="lh-copy measure-wide f4">If your node instance is 2 vCPU and 8GB of memory and the available space for pods is 1.73 vCPU and ~5.9GB of memory, your pause pod should match the latter.</p><img class="db pv3 center" src="https://learnk8s.io/a/2866bf31d1616ce105778a5f4a5820a9.svg" alt="Sizing sleep pod in overprovisioned clusters" loading="lazy"><p class="lh-copy measure-wide f4">To make sure that the Pod is evicted as soon as a real Pod is created, you can use <a href="https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Priorities and Preemptions.</a></p><p class="lh-copy measure-wide f4"><strong class="b">Pod Priority indicates the importance of a Pod relative to other Pods.</strong></p><p class="lh-copy measure-wide f4">When a Pod cannot be scheduled, the scheduler tries to preempt (evict) lower priority Pods to schedule the Pending pod.</p><p class="lh-copy measure-wide f4">You can configure Pod Priorities in your cluster with a PodPriorityClass:</p><div class="mv4 mv5-l"><header class="bg-light-gray flex pv2 pl1 br--top br2 relative"><div class="w1 h1 ml1 br-100 bg-dark-red"></div><div class="w1 h1 ml1 br-100 bg-green"></div><div class="w1 h1 ml1 br-100 bg-yellow"></div><p class="code f6 mv0 black-60 w-100 tc absolute top-0 left-0 h1 pv2">priority.yaml</p></header><pre class="code-light-theme relative overflow-auto mv0 br2 br--bottom"><code class="code lh-copy"><span class="standard"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> scheduling.k8s.io/v1 <span class="token key atrule">kind</span><span class="token punctuation">:</span> PriorityClass <span class="token key atrule">metadata</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">value</span><span class="token punctuation">:</span> <span class="token number">-1</span> <span class="token key atrule">globalDefault</span><span class="token punctuation">:</span> <span class="token boolean important">false</span> <span class="token key atrule">description</span><span class="token punctuation">:</span> <span class="token string">'Priority class used by overprovisioning.'</span></span></code></pre></div><p class="lh-copy measure-wide f4">Since the default priority for a Pod is <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">0</code> and the <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">overprovisioning</code> PriorityClass has a value of <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">-1</code>, those Pods are the first to be evicted when the cluster runs out of space.</p><p class="lh-copy measure-wide f4">PriorityClass also has two optional fields: <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">globalDefault</code> and <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">description</code>.</p><ul><li class="lh-copy f4 mv1 measure-wide">The <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">description</code> is a human-readable memo of what the PriorityClass is about.</li><li class="lh-copy f4 mv1 measure-wide">The <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">globalDefault</code> field indicates that the value of this PriorityClass should be used for Pods without a <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">priorityClassName</code>. Only one PriorityClass with <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">globalDefault</code> set to <code class="code f5 lh-copy bg-near-white br2 pv1 ph2 fs-normal word-nowrap-even-on-whitespace">true</code> can exist in the system.</li></ul><p class="lh-copy measure-wide f4">You can assign the priority to your sleep Pod with:</p><div class="mv4 mv5-l"><header class="bg-light-gray flex pv2 pl1 br--top br2 relative"><div class="w1 h1 ml1 br-100 bg-dark-red"></div><div class="w1 h1 ml1 br-100 bg-green"></div><div class="w1 h1 ml1 br-100 bg-yellow"></div><p class="code f6 mv0 black-60 w-100 tc absolute top-0 left-0 h1 pv2">overprovision.yaml</p></header><pre class="code-light-theme relative overflow-auto mv0 br2 br--bottom"><code class="code lh-copy"><span class="standard"><span class="token key atrule">apiVersion</span><span class="token punctuation">:</span> apps/v1 <span class="token key atrule">kind</span><span class="token punctuation">:</span> Deployment <span class="token key atrule">metadata</span><span class="token punctuation">:</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">spec</span><span class="token punctuation">:</span> <span class="token key atrule">replicas</span><span class="token punctuation">:</span> <span class="token number">1</span> <span class="token key atrule">selector</span><span class="token punctuation">:</span> <span class="token key atrule">matchLabels</span><span class="token punctuation">:</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">template</span><span class="token punctuation">:</span> <span class="token key atrule">metadata</span><span class="token punctuation">:</span> <span class="token key atrule">labels</span><span class="token punctuation">:</span> <span class="token key atrule">run</span><span class="token punctuation">:</span> overprovisioning <span class="token key atrule">spec</span><span class="token punctuation">:</span> </span><span class="highlight"> <span class="token key atrule">priorityClassName</span><span class="token punctuation">:</span> overprovisioning </span><span class="standard"> <span class="token key atrule">containers</span><span class="token punctuation">:</span> <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> reserve<span class="token punctuation">-</span>resources <span class="token key atrule">image</span><span class="token punctuation">:</span> registry.k8s.io/pause <span class="token key atrule">resources</span><span class="token punctuation">:</span> <span class="token key atrule">requests</span><span class="token punctuation">:</span> <span class="token key atrule">cpu</span><span class="token punctuation">:</span> <span class="token string">'1739m'</span> <span class="token key atrule">memory</span><span class="token punctuation">:</span> <span class="token string">'5.9G'</span></span></code></pre></div><p class="lh-copy measure-wide f4"><em class="i">The setup is complete!</em></p><p class="lh-copy measure-wide f4">When there are not enough resources in the cluster, the pause pod is preempted, and new pods take their place.</p><p class="lh-copy measure-wide f4">Since the pause pod become unschedulable, it forces the Cluster Autoscaler to add more nodes to the cluster.</p><p class="lh-copy measure-wide f4"><em class="i">Now that you're ready to overprovision your cluster, it's worth having a look at optimising your applications for scaling.</em></p><h2 class="f2 pt5 pb2 mt3" id="selecting-the-correct-memory-and-cpu-requests-for-your-pods">Selecting the correct memory and CPU requests for your Pods</h2><p class="lh-copy measure-wide f4"><strong class="b">The cluster autoscaler makes scaling decisions based on the presence of pending pods.</strong></p><p class="lh-copy measure-wide f4">The Kubernetes scheduler assigns (or not) a Pod to a Node based on its memory and CPU requests.</p><p class="lh-copy measure-wide f4">Hence, it's essential to set the correct requests on your workloads, or you might be triggering your autoscaler too late (or too early).</p><p class="lh-copy measure-wide f4"><em class="i">Let's have a look at an example.</em></p><p class="lh-copy measure-wide f4">You decide to profile an application, and you found out that:</p><ul><li class="lh-copy f4 mv1 measure-wide">Under average load, the application consumes 512MB of memory and 0.25 vCPU.</li><li class="lh-copy f4 mv1 measure-wide">At peak, the application should consume up to 4GB of memory and 1 vCPU.</li></ul><img class="db pv3 center" src="https://learnk8s.io/a/d44981930b1e0d843e696dd67f3b3b43.svg" alt="Setting the right memory and CPU requests" loading="lazy"><p class="lh-copy measure-wide f4">The limit for your container is 4GB of memory and 1 vCPU.</p><p class="lh-copy measure-wide f4"><em class="i">However, what about the requests?</em></p><p class="lh-copy measure-wide f4">The scheduler uses the Pod's memory and CPU requests to select the best node before creating the Pod.</p><p class="lh-copy measure-wide f4">So you could:</p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Set requests lower than the actual average usage.</strong></li><li class="lh-copy f4 mv1 measure-wide">Be conservative and <strong class="b">assign requests closer to the limit.</strong></li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Set requests to match the actual limits.</strong></li></ol><div class="relative overflow-hidden"><ul class="pl0 list"><li class="mv3"><input type="radio" name="carousel-7" id="carousel-7-0" checked class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/27a58b9c37d2e1ba3386f02c85c110ab.svg" alt="You could assign requests that are lower than the average app consumption." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">1</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><div class="w-20"></div><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">You could assign requests that are <strong class="b">lower</strong> than the average app consumption.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-7-1">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-7" id="carousel-7-1" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/73f0599244569e7f79137dfa176a53c0.svg" alt="You could assign requests that match the actual usage." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">2</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-7-0"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">You could assign requests that match the actual usage.</p></div><label class="db f6 b black-50 pv3 pointer w-20 tr ttu" for="carousel-7-2">Next <svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon ml2"><polyline fill="none" vector-effect="non-scaling-stroke" points="2,2 8,8 2,14"></polyline></svg></label></div></div></li><li class="mv3"><input type="radio" name="carousel-7" id="carousel-7-2" class="dn o-0 absolute bottom-0 left-0"><div class="dn checked-reveal"><div class="aspect-ratio aspect-ratio--4x3"><img src="https://learnk8s.io/a/d03d4b06ced262550418b8f9d52662ab.svg" alt="You could set the requests so high that they match the limits of your app." class="aspect-ratio--object" loading="lazy"></div><div class="bt b-solid bw2 b--black-70 relative mt0"><div class="bg-black-10 br1 pa1 dib mt2 absolute bottom-1 left-0 z-999"><span class="b black-60">3</span><span class="f7 black-50">/3</span></div></div><div class="flex items-start justify-between bg-evian ph2"><label class="db f6 b black-50 pv3 pointer w-20 ttu" for="carousel-7-1"><svg viewBox="0 0 10 16" xmlns="http://www.w3.org/2000/svg" class="pagination-icon mr2"><polyline fill="none" vector-effect="non-scaling-stroke" points="8,2 2,8 8,14"></polyline></svg> Previous</label><div class="f5 lh-copy black-90 w-60 center"><p class="lh-copy measure-wide f5">You could set the requests so high that they match the limits of your app.</p></div><div class="w-20"></div></div></div></li></ul></div><p class="lh-copy measure-wide f4"><strong class="b">Defining requests lower than the actual usage is problematic since your nodes will be often overcommitted.</strong></p><p class="lh-copy measure-wide f4">As an example, you can assign 256MB of memory as a memory request.</p><p class="lh-copy measure-wide f4">The Kubernetes scheduler can fit twice as many Pods for each node.</p><p class="lh-copy measure-wide f4">However, Pods use twice as much memory in practice and start competing for resources (CPU) and being evicted (not enough memory on the Node).</p><img class="db pv3 center" src="https://learnk8s.io/a/22fdf4559d43e563b3b9b0472ea68969.svg" alt="Overcommitting nodes" loading="lazy"><p class="lh-copy measure-wide f4"><strong class="b">Overcommitting nodes can lead to excessive evictions, more work for the kubelet and a lot of rescheduling.</strong></p><p class="lh-copy measure-wide f4"><em class="i">What happens if you set the request to the same value of the limit?</em></p><p class="lh-copy measure-wide f4">You can set request and limits to the same values.</p><p class="lh-copy measure-wide f4">In Kubernetes, this is often referred to as <a href="https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#qos-classes" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Guaranteed Quality of Service class</a> and refers to the fact that it's improbable that the pod will be terminated and evicted.</p><p class="lh-copy measure-wide f4">The Kubernetes scheduler will reserve the entire CPU and memory for the Pod on the assigned node.</p><p class="lh-copy measure-wide f4"><strong class="b">Pods with Guaranteed Quality of Service are stable but also inefficient.</strong></p><p class="lh-copy measure-wide f4">If your app uses 512MB of memory on average, but you reserve 4GB for it, you have 3.5GB unused most of the time.</p><img class="db pv3 center" src="https://learnk8s.io/a/3661626fe6a72a79770b9f8e2139e015.svg" alt="Overcommitting nodes" loading="lazy"><p class="lh-copy measure-wide f4"><em class="i">Is it worth it?</em></p><p class="lh-copy measure-wide f4">If you want extra stability, yes.</p><p class="lh-copy measure-wide f4">If you want efficiency, you might want to lower the requests and leave a gap between those and the limit.</p><p class="lh-copy measure-wide f4">This is often referred to as <strong class="b">Burstable Quality of Service class</strong> and refers to the fact that the Pod baseline consumption can occasionally burst into using more memory and CPU.</p><p class="lh-copy measure-wide f4">When your requests match the app's actual usage, the scheduler will pack your pods in your nodes efficiently.</p><p class="lh-copy measure-wide f4"><strong class="b">Occasionally, the app might require more memory or CPU.</strong></p><ol><li class="lh-copy f4 mv1 measure-wide">If there are resources in the Node, the app will use them before returning to the baseline consumption.</li><li class="lh-copy f4 mv1 measure-wide">If the node is low on resources, the pod will compete for resources (CPU), and the kubelet might try to evict the Pod (memory).</li></ol><p class="lh-copy measure-wide f4"><em class="i">Should you use Guaranteed or Burstable quality of Service?</em></p><p class="lh-copy measure-wide f4"><em class="i">It depends.</em></p><ol><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Use Guaranteed Quality of Service (requests equal to limits) when you want to minimise rescheduling and evictions for the Pod.</strong> An excellent example is a Pod for a database.</li><li class="lh-copy f4 mv1 measure-wide"><strong class="b">Use Burstable Quality of Service (requests to match actual average usage) when you want to optimise your cluster and use the resources wisely.</strong> If you have a web application or a REST API, you might want to use a Burstable Quality of Service.</li></ol><p class="lh-copy measure-wide f4"><em class="i">How do you select the correct requests and limits values?</em></p><p class="lh-copy measure-wide f4"><strong class="b">You should profile the application and measure memory and CPU consumption when idle, under load and at peak.</strong></p><p class="lh-copy measure-wide f4">A more straightforward strategy consists of deploying the Vertical Pod Autoscaler and wait for it to suggest the correct values.</p><p class="lh-copy measure-wide f4">The Vertical Pod Autoscaler collects the data from the Pod and applies a regression model to extrapolate requests and limits.</p><p class="lh-copy measure-wide f4"><a href="https://learnk8s.io/setting-cpu-memory-limits-requests" target="_blank" rel="noreferrer" class="link navy underline hover-sky">You can learn more about how to do that in this article.</a></p><h2 class="f2 pt5 pb2 mt3" id="what-about-downscaling-a-cluster-">What about downscaling a cluster?</h2><p class="lh-copy measure-wide f4"><strong class="b">Every 10 seconds, the Cluster Autoscaler decides to remove a node only when the request utilization falls below 50%.</strong></p><p class="lh-copy measure-wide f4">In other words, for all the pods on the same node, it sums the CPU and memory requests.</p><p class="lh-copy measure-wide f4">If they are lower than half of the node's capacity, the Cluster Autoscaler will consider the current node for downscaling.</p><blockquote class="pl3 mh2 bl bw2 b--blue bg-evian pv1 ph4"><p class="lh-copy measure-wide f4">It's worth noting that the Cluster Autoscaler does not consider actual CPU and memory usage or limits and instead only looks at resource requests.</p></blockquote><p class="lh-copy measure-wide f4">Before the node is removed, the Cluster Autoscaler executes:</p><ul><li class="lh-copy f4 mv1 measure-wide"><a href="https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Pods checks</a> to make sure that the Pods can be moved to other nodes.</li><li class="lh-copy f4 mv1 measure-wide"><a href="https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#i-have-a-couple-of-nodes-with-low-utilization-but-they-are-not-scaled-down-why" target="_blank" rel="noreferrer" class="link navy underline hover-sky">Nodes checks</a> to prevent nodes from being destroyed prematurely.</li></ul><p class="lh-copy measure-wide f4">If the checks pass, the Cluster Autoscaler will remove the node from the cluster.</p><h2 class="f2 pt5 pb2 mt3" id="why-not-autoscaling-based-on-memory-or-cpu-">Why not autoscaling based on memory or CPU?</h2><p class="lh-copy measure-wide f4"><strong class="b">CPU or memory-based cluster autoscalers don't care about pods when scaling up and down.</strong></p><p class="lh-copy measure-wide f4">Imagine having a cluster with a single node and setting up the autoscaler to add a new node with the CPU reaches 80% of the total capacity.</p><p class="lh-copy measure-wide f4">You decide to create a Deployment with 3 replicas.</p><p class="lh-copy measure-wide f4">The combined resource usage for the three pods reaches 85% of the CPU.</p><p class="lh-copy measure-wide f4">A new node is provisioned.</p><p class="lh-copy measure-wide f4"><em class="i">What if you don't need any more pods?</em></p><p class="lh-copy measure-wide f4">You have a full node idling — not great.</p><p class="lh-copy measure-wide f4"><strong class="b">Usage of these type of autoscalers with Kubernetes is discouraged.</strong></p><h2 class="f2 pt5 pb2 mt3" id="summary">Summary</h2><p class="lh-copy measure-wide f4">Defining and implementing a successful scaling strategy in Kubernetes requires you to master several subjects:</p><ul><li class="lh-copy f4 mv1 measure-wide">Allocatable resources in Kubernetes nodes.</li><li class="lh-copy f4 mv1 measure-wide">Fine-tuning refresh intervals for Metrics Server, Horizontal Pod Autoscaler and Cluster Autoscalers.</li><li class="lh-copy f4 mv1 measure-wide">Architecting cluster and node instance sizes.</li><li class="lh-copy f4 mv1 measure-wide">Container image caching.</li><li class="lh-copy f4 mv1 measure-wide">Application benchmarking and profiling.</li></ul><p class="lh-copy measure-wide f4">But with the proper monitoring tool, you can iteratively test your scaling strategy and tune the speed and costs of your cluster.</p></article><div class="mb4 mb5-l mw8 center"><ul class="list pl0 flex flex-wrap"><li class="w-50-ns f5 bg-evian br2 ph4"><p class="pb3 f2 b navy mb2 b mt4">What is Learnk8s?</p><p class="lh-copy f4 measure-narrow pt0 mt0">In-depth Kubernetes training that is practical and easy to understand.</p></li><li class="w-50-ns f5 ph4 pv2"><a class="link dib f3 navy b bb bw1 pb3 mb3 pt3 hover-sky" href="/training">⎈ Instructor-led workshops <span class="f5 v-mid dib pb1 pl1">❯</span></a><p class="lh-copy f4 measure-narrow pt0 mt0">Deep dive into containers and Kubernetes with the help of our instructors and become an expert in deploying applications at scale.</p></li><li class="w-50-ns f5 ph4 pv2"><a class="link dib f3 navy b bb bw1 pb3 mb3 pt3 hover-sky" href="/academy">⎈ Online courses <span class="f5 v-mid dib pb1 pl1">❯</span></a><p class="lh-copy f4 measure-narrow pt0 mt0">Learn Kubernetes online with hands-on, self-paced courses. No need to leave the comfort of your home.</p></li><li class="w-50-ns f5 ph4 pv2"><a class="link dib f3 navy b bb bw1 pb3 mb3 pt3 hover-sky" href="/corporate-training">⎈ Corporate training <span class="f5 v-mid dib pb1 pl1">❯</span></a><p class="lh-copy f4 measure-narrow pt0 mt0">Train your team in containers and Kubernetes with a customised learning path — remotely or on-site.</p></li></ul></div><footer class="footer ph3 ph4-ns pt3 pb3 bg-sky bt bw3 b--white-20"><section class="mw6 center mw-100-l flex-l items-start-l justify-around-l pv2"><div class=""><a href="/" class="logo w4 db" title="Learnk8s logo"><svg xmlns="http://www.w3.org/2000/svg" fill="white" viewBox="0 0 139 52"><path d="M37.11 24.48c-.993 0-1.833.84-1.833 1.832 0 .993.84 1.833 1.832 1.833.993 0 1.833-.84 1.833-1.833 0-.992-.84-1.832-1.833-1.832"></path><path d="M37.11 30.468c-1.451 0-2.75-.764-3.437-1.91a52.731 52.731 0 0 0-1.603 4.353c-1.68 4.658-2.825 7.636-4.276 8.705-.764.763-1.756 1.221-2.978 1.221a4.106 4.106 0 0 1-4.123-4.123c0-1.45.763-2.749 1.909-3.436a52.731 52.731 0 0 0-4.353-1.603c-4.657-1.68-7.635-2.825-8.704-4.276-.764-.764-1.222-1.756-1.222-2.978a4.106 4.106 0 0 1 4.123-4.123c1.451 0 2.75.763 3.436 1.909a52.772 52.772 0 0 0 1.604-4.353c1.68-4.657 2.825-7.635 4.276-8.704.763-.764 1.756-1.222 2.978-1.222a4.106 4.106 0 0 1 4.123 4.123c0 1.45-.764 2.749-1.909 3.436 1.45.611 3.13 1.222 4.352 1.604 4.658 1.68 7.636 2.825 8.705 4.276.764.763 1.222 1.756 1.222 2.978 0 2.214-1.833 4.123-4.124 4.123M27.336 2.445c-.993-.993-2.52-.993-3.513 0L1.757 24.512c-.993.993-.993 2.52 0 3.512l22.066 22.067c.993.993 2.52.993 3.513 0l22.067-22.067c.992-.992.992-2.52 0-3.512L27.336 2.445z"></path><path d="M12.424 24.48c-.992 0-1.832.84-1.832 1.832 0 .993.84 1.833 1.832 1.833.993 0 1.833-.84 1.833-1.833 0-.992-.84-1.832-1.833-1.832m12.343 12.342c-.993 0-1.833.84-1.833 1.833s.84 1.832 1.833 1.832c.992 0 1.832-.84 1.832-1.832 0-.993-.84-1.833-1.832-1.833M21.884 16.87c-.229-.23-.458-.459-.61-.764a52.731 52.731 0 0 0-1.604 4.352c-1.68 4.658-2.825 7.636-4.276 8.705-.23.229-.458.458-.764.61a52.639 52.639 0 0 0 4.353 1.604c4.657 1.68 7.635 2.825 8.704 4.276.23.229.458.458.611.763.61-1.45 1.222-3.13 1.603-4.352 1.68-4.658 2.826-7.635 4.276-8.704.23-.23.459-.459.764-.611a52.731 52.731 0 0 0-4.352-1.604c-4.658-1.603-7.712-2.749-8.705-4.276m2.883-1.111c.992 0 1.832-.84 1.832-1.833s-.84-1.833-1.832-1.833c-.993 0-1.833.84-1.833 1.833 0 1.069.84 1.833 1.833 1.833m36.766 14.957c-.153-.153-.23-.306-.23-.458-.076-.23-.076-.458-.076-.764V16.665l-1.909.306v12.751c0 .993.23 1.756.764 2.215.458.458 1.298.763 2.52.763l.229-1.603c-.306-.077-.535-.077-.764-.153a.693.693 0 0 1-.534-.23m4.847-4.52c.075-.382.152-.763.228-1.069.153-.382.306-.687.535-.916.229-.306.534-.458.84-.687.305-.153.687-.23 1.145-.23.763 0 1.374.306 1.832.84.459.535.688 1.222.611 2.138H66.38zm2.824-4.581c-.61 0-1.221.152-1.832.381-.611.23-1.07.611-1.527 1.07a4.532 4.532 0 0 0-1.07 1.756c-.305.687-.381 1.527-.381 2.443 0 .84.076 1.527.305 2.214a5.01 5.01 0 0 0 .993 1.757c.458.458.992.84 1.68 1.145.687.305 1.45.382 2.367.382a7.88 7.88 0 0 0 1.985-.23c.61-.152.993-.228 1.222-.381l-.23-1.604c-.228.077-.61.23-1.068.306-.458.153-.993.153-1.68.153-1.222 0-2.062-.306-2.596-.84-.535-.535-.917-1.375-.993-2.52h7.254v-.687c0-1.833-.382-3.207-1.145-4.047-.764-.84-1.91-1.298-3.284-1.298m12.826 9.45c-.23.077-.535.077-.84.077h-1.222c-.764 0-1.375-.153-1.756-.382-.459-.23-.688-.764-.688-1.451 0-.382.077-.687.23-.916.152-.23.381-.382.687-.535s.534-.229.916-.229c.305-.076.61-.076.916-.076.458 0 .84 0 1.145.076.306.077.535.077.688.153v3.283zm.992-8.323c-.305-.381-.764-.61-1.298-.84-.535-.229-1.145-.305-1.909-.305-.687 0-1.298.076-1.833.153-.534.076-.992.229-1.221.305l.229 1.604c.229-.077.61-.153 1.069-.306a9.723 9.723 0 0 1 1.68-.153c.458 0 .916.077 1.221.23s.535.305.764.61c.153.23.305.535.382.84.076.306.076.611.076.917v.534c-.076 0-.153 0-.305-.076-.153 0-.306-.077-.459-.077-.152 0-.381-.076-.61-.076h-.611c-.611 0-1.146.076-1.756.153-.535.152-.993.305-1.451.61-.382.23-.764.611-.993.993-.229.458-.382.916-.382 1.527 0 .611.077 1.146.306 1.604s.458.763.84 1.069c.382.229.84.458 1.298.61.534.153 1.069.153 1.68.153.458 0 .84 0 1.298-.076.458 0 .84-.076 1.221-.076.382-.077.688-.077.993-.153.305-.076.535-.076.687-.076v-6.643c0-.611-.076-1.146-.229-1.68a3.876 3.876 0 0 0-.687-1.375m9.128-.94c-.229 0-.382-.076-.61-.076h-.535c-.84 0-1.604.076-2.215.229-.687.153-1.221.305-1.68.458v10.155h1.91v-8.933c.076 0 .305-.077.687-.153.382-.076.687-.076 1.069-.076.534 0 .992.076 1.374.076.382.076.611.153.764.229l.305-1.68c-.076 0-.229-.076-.382-.076-.305-.077-.458-.153-.687-.153m10.503 1.264c-.305-.458-.763-.763-1.374-.993-.534-.229-1.298-.381-2.138-.381-.916 0-1.756.076-2.52.152-.687.153-1.298.23-1.756.382v10.308h1.909v-9.01c.076 0 .153 0 .305-.076.153 0 .306-.076.535-.076.229 0 .382 0 .61-.077h.612c.534 0 .916.077 1.298.23.305.152.61.305.84.61.229.306.381.687.458 1.145.076.459.152.993.152 1.68v5.574h1.91v-5.956c0-.687-.077-1.374-.23-1.985-.076-.61-.305-1.145-.61-1.527m12.032 6.312c-.381-.535-.84-1.07-1.298-1.604a10.45 10.45 0 0 0-1.298-1.298c.84-.84 1.604-1.603 2.291-2.367a618.04 618.04 0 0 1 2.138-2.367h-3.589c-.229.229-.382.534-.687.84-.229.305-.534.61-.84.992-.305.382-.61.688-.916 1.07-.306.381-.611.687-.916.992v-9.01l-3.055.458v15.424h3.055v-4.734c.305.305.687.61 1.069.993.381.381.687.84.992 1.221.306.459.611.84.916 1.298.306.459.535.84.764 1.146h3.512c-.229-.458-.534-.916-.84-1.527-.458-.382-.84-.917-1.298-1.527m9.547.514c-.305.306-.84.535-1.527.535-.382 0-.687-.076-.916-.152a1.663 1.663 0 0 1-.61-.382 2.32 2.32 0 0 1-.383-.535c-.076-.229-.076-.381-.076-.534 0-.535.153-.993.382-1.375.229-.381.61-.687.992-.992.382.152.764.229 1.07.382.305.152.61.305.84.458.228.152.457.381.61.61.153.23.23.535.23.84a2.12 2.12 0 0 1-.612 1.146m-3.13-8.4c.076-.152.152-.381.305-.534.153-.153.306-.305.535-.382.229-.076.458-.152.763-.152.306 0 .611.076.764.152.229.077.382.23.534.382a1.6 1.6 0 0 1 .306.458c.076.153.076.306.076.458 0 .535-.153.917-.382 1.298a2.32 2.32 0 0 1-.992.917c-.764-.306-1.298-.611-1.68-.993-.306-.382-.458-.763-.458-1.222.076 0 .152-.152.229-.381m4.505 3.588c.534-.305.916-.763 1.298-1.374.382-.535.534-1.145.534-1.833 0-.458-.076-.916-.229-1.374-.153-.458-.458-.84-.84-1.222a3.941 3.941 0 0 0-1.45-.916 5.942 5.942 0 0 0-2.138-.382c-.688 0-1.375.077-1.91.306a3.943 3.943 0 0 0-1.45.916c-.382.382-.764.84-.916 1.298-.23.534-.306.993-.306 1.603 0 .688.153 1.299.382 1.757a5.37 5.37 0 0 0 1.298 1.374 7.12 7.12 0 0 0-.764.687c-.229.23-.458.458-.61.764-.23.305-.306.61-.459.916a4.621 4.621 0 0 0-.152 1.145c0 .382.076.84.229 1.299.153.458.458.916.84 1.298a4.42 4.42 0 0 0 1.527.992c.61.23 1.45.382 2.367.382.84 0 1.527-.076 2.214-.305a5.493 5.493 0 0 0 1.604-.917c.458-.381.763-.84.916-1.374.23-.535.305-1.07.305-1.68 0-.764-.152-1.374-.534-1.909-.458-.458-.993-.992-1.756-1.45m11.836 3.327c-.076-.306-.305-.688-.534-.917-.23-.305-.611-.534-1.07-.763-.458-.23-.992-.458-1.68-.764-.305-.153-.61-.229-.84-.305-.228-.077-.38-.23-.534-.306-.152-.076-.229-.152-.229-.305-.076-.076-.076-.23-.076-.306 0-.534.458-.763 1.45-.763.535 0 .993.076 1.375.153.382.076.764.229 1.145.305l.535-2.367c-.382-.153-.84-.229-1.45-.382-.612-.152-1.223-.152-1.91-.152-1.298 0-2.367.305-3.054.916s-1.145 1.374-1.145 2.367c0 .534.076.992.229 1.298.152.382.382.687.61.916.306.23.611.458.993.687.382.23.84.382 1.298.535.611.229 1.07.458 1.375.61.305.153.458.383.458.612 0 .305-.153.534-.382.61-.229.077-.61.153-1.222.153-.534 0-1.069-.076-1.603-.153l-1.604-.458-.534 2.444c.229.076.687.229 1.298.381.61.153 1.45.23 2.367.23 1.45 0 2.596-.306 3.36-.84.763-.535 1.221-1.375 1.221-2.444.306-.229.23-.61.153-.992"></path></svg></a><p class="f5 white">The Kubernetes training company.</p><ul class="pl3 mv0 f5 lh-copy white"><li><a href="/contact-us" class="link white underline-hover b">Contact us</a></li><li><a href="/about-us" class="link white underline-hover b">Team</a></li><li><a href="/careers" class="link white underline-hover b">Careers</a></li></ul><ul class="list pl0"><li class="dib"><a href="https://twitter.com/learnk8s" class="link dib w2 h2 icon" title="Learnk8s on Twitter" rel="noreferrer" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" class=""><path fill="#ffffff" d="M50.2 12.7c-1.7 1-3.5 1.8-5.5 2.2-1.6-1.8-3.8-2.9-6.3-2.9-4.8 0-8.6 4.1-8.6 9.1 0 .7.1 1.4.2 2.1-7.2-.4-13.5-4-17.8-9.5-.7 1.3-1.2 2.9-1.2 4.6 0 3.2 1.5 5.9 3.8 7.6-1.4 0-2.7-.5-3.9-1.1v.1c0 4.4 3 8.1 6.9 8.9-.7.2-1.5.3-2.3.3-.6 0-1.1-.1-1.6-.2 1.1 3.6 4.3 6.2 8 6.3-3 2.4-6.7 3.9-10.7 3.9-.7 0-1.4 0-2.1-.1 3.8 2.6 8.3 4.1 13.2 4.1C38.4 48 47 34.2 47 22.1v-1.2c1.7-1.3 3.1-2.9 4.3-4.7-1.5.7-3.2 1.2-4.9 1.4 1.7-1 3.1-2.8 3.8-4.9z"></path></svg></a></li><li class="dib"><a href="https://www.linkedin.com/company/learnk8s/" class="link dib w2 h2 icon" title="Learnk8s on LinkedIn" rel="noreferrer" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" class=""><path fill="#ffffff" d="M14.8 10c-2.9 0-4.8 2-4.8 4.7 0 2.6 1.8 4.7 4.7 4.7h.1c2.9 0 4.8-2.1 4.8-4.7-.2-2.7-2-4.7-4.8-4.7zM11 22.8h7.8V50H11zM40.1 22.6c-4.5 0-7.3 2.7-7.8 4.5v-4.3h-8.8c.1 2.3 0 27.2 0 27.2h8.8V35.3c0-.8 0-1.6.2-2.2.6-1.6 1.9-3.3 4.2-3.3 3 0 4.4 2.5 4.4 6.2v14H50V34.9c0-8.4-4.4-12.3-9.9-12.3z"></path></svg></a></li><li class="dib"><a href="/slack" class="link dib w2 h2 icon" title="Learnk8s on Slack" rel="noreferrer" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60"><path fill="#ffffff" d="M25.913 27.84l5.88-1.968 1.904 5.69-5.88 1.968z"></path><path fill="#ffffff" d="M24 9.8C8.8 14.4 5.3 20.9 9.8 36 14.4 51.2 20.9 54.7 36 50.2 51.2 45.6 54.7 39.1 50.2 24 45.6 8.8 39.1 5.3 24 9.8zm18.5 24l-2.9 1 1 3c.4 1.2-.2 2.5-1.4 2.9-.3.1-.5.1-.8.1-.9 0-1.8-.6-2.1-1.6l-1-2.9-5.9 2 1 2.9c.4 1.2-.2 2.5-1.4 2.9-.3.1-.5.1-.8.1-.9 0-1.8-.6-2.1-1.6l-1-3-2.9 1c-.3.1-.5.1-.8.1-.9 0-1.8-.6-2.1-1.6-.4-1.2.2-2.5 1.4-2.9l2.9-1-1.9-5.7-2.9 1c-.3.1-.5.1-.8.1-.9 0-1.8-.6-2.1-1.6-.4-1.2.2-2.5 1.4-2.9l2.9-1-1-2.9c-.4-1.2.2-2.5 1.4-2.9 1.2-.4 2.5.2 2.9 1.4l1 2.9 5.9-2-1-2.9c-.4-1.2.2-2.5 1.4-2.9 1.2-.4 2.5.2 2.9 1.4l1 3 2.9-1c1.2-.4 2.5.2 2.9 1.4.4 1.2-.2 2.5-1.4 2.9l-2.9 1 1.9 5.7 2.9-1c1.2-.4 2.5.2 2.9 1.4.5 1.5-.2 2.8-1.4 3.2z"></path></svg></a></li><li class="dib"><a href="/telegram" class="link dib w2 h2 icon" title="Learnk8s on Telegram" rel="noreferrer" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" viewBox="-6 -6 60 60" class=""><path d="M0 24c0 13.255 10.745 24 24 24s24-10.745 24-24S37.255 0 24 0 0 10.745 0 24zm19.6 11l.408-6.118 11.129-10.043c.488-.433-.107-.645-.755-.252l-13.735 8.665-5.932-1.851c-1.281-.393-1.29-1.273.287-1.906l23.118-8.914c1.056-.48 2.075.254 1.672 1.87l-3.937 18.552c-.275 1.319-1.071 1.634-2.175 1.025l-5.997-4.431L20.8 34.4l-.027.026c-.322.314-.59.574-1.173.574z" fill="#ffffff"></path></svg></a></li><li class="dib"><a class="link dib w2 h2 icon" title="Learnk8s on Mastodon" rel="me" href="https://learnk8s.news/@learnk8s" target="_blank"><svg viewBox="0 0 64 64" fill="none" class="pl1" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M57.449 38.26c-.863 4.439-7.728 9.296-15.612 10.238-4.112.49-8.16.941-12.477.744-7.058-.323-12.63-1.685-12.63-1.685 0 .687.042 1.342.126 1.954.918 6.966 6.909 7.383 12.584 7.578 5.726.196 10.826-1.413 10.826-1.413l.236 5.18s-4.006 2.15-11.142 2.546c-3.935.216-8.82-.099-14.513-1.605C2.503 58.53.382 45.373.057 32.022c-.1-3.964-.038-7.701-.038-10.827 0-13.65 8.944-17.65 8.944-17.65C13.473 1.472 21.213.601 29.257.535h.197c8.045.066 15.789.937 20.299 3.008 0 0 8.944 4.001 8.944 17.651 0 0 .112 10.072-1.248 17.064Z" fill="#ffffff"></path><path d="M12.4 17.887a3.598 3.598 0 1 1 7.197 0 3.598 3.598 0 0 1-7.197 0Zm51.59 4.367v16.53h-6.548V22.74c0-3.382-1.423-5.097-4.269-5.097-3.146 0-4.724 2.037-4.724 6.062v8.781h-6.51v-8.782c0-4.027-1.577-6.062-4.723-6.062-2.846 0-4.269 1.716-4.269 5.097v16.043H26.4V22.254c0-3.377.86-6.062 2.587-8.05 1.783-1.984 4.116-3.003 7.011-3.003 3.351 0 5.89 1.288 7.566 3.864l1.632 2.734 1.631-2.734c1.678-2.576 4.216-3.864 7.567-3.864 2.895 0 5.23 1.018 7.011 3.004 1.747 1.987 2.586 4.672 2.586 8.05Z" fill="#569ad1"></path></g><defs><clippath id="a"><path fill="#fff" d="M0 0h64v64H0z"></path></clippath></defs></svg></a></li></ul></div><div class="mv4 mv0-l"><div class="f4 measure"><p class="ttu b f6 white-60 mv2">Services</p><ul class="pl3 mv0 f5 lh-copy white-60"><li><a href="/corporate-training" class="link white-80 underline-hover pointer db">Corporate training</a></li><li><a href="/training" class="link white-80 underline-hover pointer db">Public workshops</a></li><li><a href="/sponsorships" class="link white-80 underline-hover pointer db">Sponsorships</a></li><li><a href="/consulting" class="link white-80 underline-hover pointer db">Consulting</a></li></ul></div></div><div class="mv4 mv0-l"><div class="f4 measure"><p class="ttu b f6 white-60 mv2">Tools</p><ul class="pl3 mv0 f5 lh-copy white-60"><li><a href="/kubernetes-instance-calculator" class="link white-80 underline-hover pointer db">Kubernetes instance calculator</a></li><li><a href="/troubleshooting-deployments" class="link white-80 underline-hover pointer db">Troubleshooting flow chart</a></li><li><a href="/production-best-practices" class="link white-80 underline-hover pointer db">Kubernetes production best practices</a></li><li><a href="/kubernetes-resources" class="link white-80 underline-hover pointer db">See all tools</a></li></ul></div></div><div class="mv4 mv0-l"><div class="f4 measure"><p class="ttu b f6 white-60 mv2">Research</p><ul class="pl3 mv0 f5 lh-copy white-60"><li><a href="https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Ingress controller comparison</a></li><li><a href="https://docs.google.com/spreadsheets/d/1RPpyDOLFmcgxMCpABDzrsBYWpPYCIBuvAoUQLwOGoQw" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Managed services comparison</a></li><li><a href="https://docs.google.com/spreadsheets/d/1yhkuBJBY2iO2Ax5FcbDMdWD5QLTVO6Y_kYt_VumnEtI" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Resource allocations in Kubernetes nodes</a></li><li><a href="/research" class="link white-80 underline-hover pointer db">See all research</a></li></ul></div></div><div class="mv4 mv0-l"><div class="f4 measure"><p class="ttu b f6 white-60 mv2">Our network</p><ul class="pl3 mv0 f5 lh-copy white-60"><li><a href="https://kube.fm" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">KubeFM</a></li><li><a href="https://kube.events" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Kube Events</a></li><li><a href="https://kube.careers" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Kube Careers</a></li><li><a href="https://k8sarchitect.io" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Kubernetes Architect</a></li><li><a href="https://kubesploit.io" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">Kubesploit</a></li><li><a href="https://k3sdaily.io" class="link white-80 underline-hover pointer db" target="_blank" rel="noreferrer">K3s Daily</a></li><li><a href="/news" class="link white-80 underline-hover pointer db">See all</a></li></ul></div></div></section><section class="pt2"><p class="mv0 f7 bt b--white-60 pt2 pb0 white-80">Copyright © Learnk8s 2017-2024. Made with <span class="dark-red">❤︎</span> in London. View our <a class="link white-80" href="/terms-and-conditions">Terms and Conditions</a> or <a class="link white-80" href="/privacy-policy">Privacy Policy</a>. Kubernetes is a registered trademark of The Linux Foundation.</p></section></footer><div class="js-subscribe-popup fixed bottom-1 left-0 mw5 w-100 dn"><div class="bg-evian pa3 br2 br--right shadow-4"><p class="mv0 black-80 b f4">Your source for Kubernetes news</p><div class="pv2"></div><form method="POST" action="/newsletter"><ul class="list pl0 mv0"><li><label for="subscribe-occasional" class="flex items-top"><input id="subscribe-occasional" name="subscribe-occasional" type="checkbox" class="w1 h1 flex-shrink-0 mt1" checked><span class="flex-auto pl2">Let me know when you publish <span class="b">another article like this.</span></span></label></li><li class="mt2"><label for="subscribe-weekly" class="flex items-top"><input id="subscribe-weekly" name="subscribe-weekly" type="checkbox" class="w1 h1 flex-shrink-0 mt1" checked><span class="flex-auto pl2">Sign me up for a <span class="b">weekly Kubernetes digest.</span></span></label></li></ul><div class="pv2"></div><input type="hidden" name="hp"><input type="email" class="ba b--black-20 pa2 db w-100 br1 input-reset" name="email" id="subscribe-email"><div class="bg-azure-8 bb bw2 b--azure-4 mv2 pa1 br2 hover-bg-azure-7 pointer"><button class="bn bg-transparent pa0 db w-100 pointer" name="submit"><span class="db brown-0 pa2 b f5 ba b--azure-4 tc">Subscribe</span></button></div></form><div class="js-success dn"><p class="bg-light-green ba b--green black-80 pa2 bw1 br2 mv0 b flex items-center"><svg viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg" class="w1 pr2"><g fill="none" fill-rule="evenodd"><circle fill="#EEECF5" cx="15" cy="15" r="15"></circle><circle fill="#FFF" cx="15" cy="15" r="12.188"></circle><circle fill="#3BDBB8" cx="15" cy="15" r="15"></circle><path d="M22.103 11.844c0 .23-.092.46-.257.626l-7.917 7.917a.893.893 0 01-1.252 0l-4.585-4.585a.893.893 0 010-1.252l1.252-1.25a.893.893 0 011.252 0l2.708 2.714 6.039-6.048a.893.893 0 011.25 0l1.252 1.252c.166.166.26.396.26.625l-.002.001z" fill="#FFF"></path></g></svg> You are in!</p></div><div class="pt2 pb3"><p class="mv0 lh-copy f6"><a href="/news" class="link blue-1 underline" target="_blank">More K8s news, events and jobs.</a></p></div><button class="bg-transparent bn db tc w-100 f7 ttu gray pointer underline-hover" name="close">Close</button></div></div></div><script>!function(){if(["IntersectionObserver","fetch"].some((e=>!(e in window))))return;if(!function(){const e=document.cookie.split(";").find((e=>/lastDismissedAt/.test(e)));if(void 0===e)return!0;const[t,n]=e.split("="),s=parseInt(n??"0",10);return"lastDismissedAt"===t?.trim()&&Number.isFinite(s)&&s<Date.now()-15552e6}())return;const e=window.innerWidth,t=document.querySelector("article")?.getBoundingClientRect().width;if(!t)return;if(!((e-t)/2>t/3))return;const n=Array.from(document.querySelectorAll("article > p"))[40];if(!n)return;const s=document.querySelector(".js-subscribe-popup");if(!s)return;s.classList.remove("dn");const r=new IntersectionObserver((e=>{e.forEach((e=>{e.isIntersecting&&(s.classList.add("js-popup-opened"),s.addEventListener("mouseup",(e=>{e.target instanceof HTMLElement&&"close"===e.target.getAttribute("name")&&(e.preventDefault(),s.classList.add("dn"),i())})),s.addEventListener("submit",(e=>{e.preventDefault();const t=e.target;fetch(`${t.action}?ajax`,{method:t.method,body:new URLSearchParams([...new FormData(t)])}).then((()=>{t.parentElement?.querySelector(".js-success")?.classList.remove("dn"),i()})).catch((()=>{}))})),r.unobserve(n))}))}),{threshold:1});function i(){document.cookie=`lastDismissedAt=${Date.now()};`}r.observe(n)}();</script></body></html>