Kubernetes Cordon: How It Works And When To Use It 
Tags: cloud, kubernetes, devops, finops
Published: 2022-11-18 11:23:15

<!-- wp:paragraph -->
<p>Kubernetes gives you the option to administer and maintain nodes manually. Using kubectl, you can easily create a node object and modify nodes - for example, set a label or mark it unschedulable. <strong>This is where Kubernetes cordon comes in</strong>. What is the Kubernetes cordon command, and how do you use it? Read this article to find out.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-what-is-kubernetes-cordon">What is Kubernetes cordon?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Kubernetes cordon is an operation that marks or taints a node in your existing node pool as unschedulable. By using it on a node, you can be sure that no new pods will be scheduled for this node. The command prevents the Kubernetes scheduler from placing new pods onto that node, but it doesn’t affect existing pods on that node.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To mark a node unschedulable, all it takes is running this command:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>kubectl cordon $NODENAME</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Note that you can run pods that are part of a DaemonSet on an unschedulable Node. That’s because DaemonSets usually provide node-local services that should be running on the node, even if it’s marked as unschedulable and drained of workloads.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-when-do-you-use-the-kubernetes-cordon">When do you use the Kubernetes cordon?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Nodes in a Kubernetes cluster may require maintenance - be it replacing hardware components in a self-hosted installation, updating the node’s kernel, or resizing its compute resources from a cloud provider.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes cordon and drain prepare your application for node downtime by letting workloads running on a target node get rescheduled to other ones. You can then safely shut the node down and remove it from your cluster, confident that this doesn’t impact service availability in any way.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-how-does-kubernetes-cordon-work-step-by-step-guide">How does Kubernetes cordon work - step-by-step guide</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 id="h-step-1-cordoning-a-node">Step 1: Cordoning a node</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>By cordoning a node, you mark it as unavailable to the scheduler. This makes the node not eligible to host any new pods that will be added to your cluster.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To place a cordon around a named node, use this command:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>$ kubectl cordon node-12</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The existing pods on this node won’t be affected by this and will remain accessible.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Want to check which nodes are cordoned at the moment? Use the get nodes command:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>$ kubectl get nodes

NAME&nbsp; &nbsp; STATUS&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;                    ROLES&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;               AGE&nbsp;  VERSION

node-12 Ready,SchedulingDisabled &nbsp; control-plane,master&nbsp; 22m &nbsp; v1.23.3</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>All the cordoned nodes will appear with the status SchedulingDisabled.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 id="h-step-2-draining-a-node">Step 2: Draining a node</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To empty the node from the remaining pods, you need to drain it. This process evicts the pods so they can be rescheduled to other nodes in your cluster. You can gracefully terminate pods before forcing them to be removed from the node you’re planning to drain.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To start the drain procedure, run kubectl drain, specifying the name of the node you’re draining:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>$ kubectl drain node-12

node/node-12 already cordoned

evicting pod kube-system/storage-provisioner

evicting pod default/nginx-7c658794b9-zszdd

evicting pod kube-system/coredns-64897985d-dp6lx

pod/storage-provisioner evicted

pod/nginx-7c658794b9-zszdd evicted

pod/coredns-64897985d-dp6lx evicted

node/node-12 evicted</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Note: In practice, draining without ignoring daemonsets hardly happens, as illustrated <a href="https://youtu.be/IHrFubX5WtU?t=210" target="_blank" rel="noreferrer noopener">here</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>How does the drain procedure work? First, we have Kubernetes cordoning - it cordons the node if you haven’t done that manually. Next, it evicts running pods (even if there is no space to reschedule them). Once the node is empty, you can shut it down or destroy it. The cordon assures that no new workloads can be scheduled on this node once the drain is completed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>What happens if your pods have long grace periods?</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Kubernetes node draining might take a while if your pods happen to have long grace periods. This might become a problem if you’re looking to take a node offline quickly.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can always use the --grace-period flag to override your pod termination grace periods and force an instant eviction:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>$ kubectl drain node-12 --grace-period 0</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Use this one carefully. Some workloads might not respond well when you force them to stop without having the chance to clean up.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Another command worth knowing is one for draining node even if there are no pods managed by a ReplicationController, Job, or DaemonSet on it:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>$ kubectl deain node-12 --force</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-how-do-you-undrain-uncordon-a-node-in-kubernetes">How do you undrain/uncordon a node in Kubernetes?</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It’s possible to undrain or uncordon a node in Kubernetesn by marking this node as schedulable. Use the following command:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>kubectl uncordon NODE</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="h-using-kubernetes-cordon-for-cluster-optimization">Using Kubernetes cordon for cluster optimization</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Suppose you analyze your cluster with a third-party optimization solution and discover a great potential for cost savings. But to get there, you need to change the compute resources your cluster is running on. This is where Kubernetes taint comes in handy.</p>
<!-- /wp:paragraph -->

<!-- wp:quote {"className":"is-style-plain"} -->
<blockquote class="wp-block-quote is-style-plain"><!-- wp:paragraph -->
<p>Our customers can maximize their cost savings immediately by using Evictor - a mechanism that <strong>looks for inefficiencies and compacts your pods into fewer nodes</strong>, creating empty nodes that will be removed by the Node deletion policy.&nbsp;</p>
<!-- /wp:paragraph --></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p><strong>Once you install CAST AI using this </strong><a href="https://docs.cast.ai/getting-started/overview/"><strong>guide</strong></a><strong> and connect your cluster, you can set the Evictor policy.</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Your next step is to get rid of your existing nodes and let CAST AI create an optimized cluster. Note that depending on your workload configuration, this might cause some downtime. Evictor "plays it safe" by design not to cause any downtime, but some settings can be overwritten for it to be <a href="https://docs.cast.ai/guides/evictor/#rules-override-for-specific-pods-or-nodes" target="_blank" rel="noreferrer noopener">more aggressive</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This is what Evictor looks like in action:</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh5.googleusercontent.com/mTw7lsTAFRCkI1lKHo3ghfxUMkDUQhHFBrOG2tXwV_e005MbrkWCW76sv84g1rDQ7EHmQbbnn7f0OmrqHz3z8w8AZe-jVkUXOoYqyPv4ZVVUz2PuZRy0IZOz1BztVPPT-zXYB4KOrFl-9j__hZlEa__jWBxbRmQUcf3w_NAv-SEaXQEu0p_YvCDHxxUdFg" alt="Nodes status"/></figure>
<!-- /wp:image -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li>One node (in red below) is identified as a candidate for eviction.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Evictor automatically moves the pods to other nodes - this i called “bin-packing.”</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Once the node becomes empty, it’s deleted from the cluster.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Go back to step 1.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>One node is deleted:</p>
<!-- /wp:paragraph -->

<!-- wp:image -->
<figure class="wp-block-image"><img src="https://lh3.googleusercontent.com/CvbJT0HKvtIVkF-VJ2c4TEW5PFELbSpNvSB3_M2FCI2RMNEUq62KOadDOE1F1wFuXCFlne0zIL0X8j5D8TXceP8joxZPHwqi179FF20ZmqD49Lla4cGMr6WL90Y6XTj-uh2-oMBNGzX2pRMh9Fkima9EjPzzIg0WumcbOkPdNMu3HgLjniIHF5BvWfcuKA" alt="Reducing number of nodes"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>And at the end of the process, 3 nodes remain:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"width":549,"height":238} -->
<figure class="wp-block-image is-resized"><img src="https://lh5.googleusercontent.com/_ILRHjMKbJJKBA6J7pEcLbNRpld3zOKXcDipt3hdnjGtIbPcT5dtT5--7SiNnvjSX2zhXqiLvwXYMs3qOmo-D-0MUb99RWUMKhwhOZfc26H4ci2jZx4JtJreEe1--QnW4Rzt2VRl3IlvGEjkPv9URJS2XkmWSD2JOXLi3PgWGAjDhbBauS79MNkrZdqPBA" alt="Active nodes after optimization" width="549" height="238"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>In 10 minutes, Evictor deleted 3 nodes and left 3 nodes running to optimize the setup and cut costs.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-automate-kubernetes-node-cordoning-and-draining">Automate Kubernetes node cordoning and draining</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Changing the compute resources your nodes run on manually quickly becomes time-consuming if you’re dealing with many nodes. You can let CAST AI do the job and do the node cordoning and draining for you as part of its automated optimization mechanisms.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Connect your cluster in a <a href="https://cast.ai/blog/how-does-the-read-only-cast-ai-agent-work-and-what-data-can-it-read/">read-only mode</a> to find out how much you could save and how to get there.</p>
<!-- /wp:paragraph -->


<h5 id="h-you-re-underway-to-simplify-kubernetes">You’re underway to simplify Kubernetes</h5>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Automate Kubernetes and optimize your resource utilization for a lower cloud bill.</p>
<!-- /wp:paragraph -->