{"id":15719,"date":"2020-07-05T14:23:56","date_gmt":"2020-07-05T14:23:56","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=15719"},"modified":"2021-10-30T06:55:38","modified_gmt":"2021-10-30T06:55:38","slug":"understanding-node-selector-and-node-affinity-in-kubernetes","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/understanding-node-selector-and-node-affinity-in-kubernetes\/","title":{"rendered":"Understanding Node Selector and Node Affinity in Kubernetes"},"content":{"rendered":"\n<p>The Kubernetes scheduler can be constrained to place a pod on particular nodes using few different options. In your POD specification, there are many ways in which you declare a POD should be dedicated to specific nodes.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Node Selector<\/li><li>Node Affinity<\/li><li>Pod Affinity aka inter-pod affinity\/anti-affinity<\/li><li>Taints and Tolerations<\/li><\/ul>\n\n\n\n<p>In this post, I am going to discuss on Node Selector and Node Affinity.<\/p>\n\n\n\n<p><strong>nodeSelector<\/strong><br>nodeSelector is the simplest recommended form of node selection constraint. nodeSelector is a field of PodSpec. It specifies a map of key-value pairs. For the pod to be eligible to run on a node, the node must have each of the indicated key-value pairs as labels (it can have additional labels as well).<\/p>\n\n\n\n<p><strong>Interlude: built-in node labels<\/strong><\/p>\n\n\n\n<p>In addition to labels you attach, nodes come pre-populated with a standard set of labels. These labels are<\/p>\n\n\n\n<p>kubernetes.io\/hostname<br>failure-domain.beta.kubernetes.io\/zone<br>failure-domain.beta.kubernetes.io\/region<br>topology.kubernetes.io\/zone<br>topology.kubernetes.io\/region<br>beta.kubernetes.io\/instance-type<br>node.kubernetes.io\/instance-type<br>kubernetes.io\/os<br>kubernetes.io\/arch<\/p>\n\n\n\n<p><strong>The affinity feature consists of two types of affinity<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>node affinity&#8221; and<\/li><li>inter-pod affinity\/anti-affinity&#8221;<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-gallery columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"617\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1-1024x617.png\" alt=\"\" data-id=\"15730\" data-full-url=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1.png\" data-link=\"https:\/\/www.devopsschool.com\/blog\/understanding-node-selector-and-node-affinity-in-kubernetes\/node-selector-kubernetes1\/\" class=\"wp-image-15730\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1-1024x617.png 1024w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1-300x181.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1-768x463.png 768w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes1.png 1232w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/li><\/ul><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"817\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes2-1024x817.png\" alt=\"\" class=\"wp-image-15731\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes2-1024x817.png 1024w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes2-300x239.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes2-768x613.png 768w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-selector-kubernetes2.png 1162w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>nodeAffinity<\/strong><\/p>\n\n\n\n<p>Kubernetes also has a more nuanced way of setting affinity called nodeAffinity and podAffinity.<\/p>\n\n\n\n<p>nodeSelector provides a very simple way to constrain pods to nodes with particular labels. Node affinity is conceptually similar to nodeSelector but nodeAffinity allows users to <strong>more expressive way pods to nodes<\/strong> with particular labels.<\/p>\n\n\n\n<p><strong>The affinity\/anti-affinity feature, greatly expands the types of constraints you can express. The key enhancements are<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>The affinity\/anti-affinity language is more expressive. The language offers more matching rules besides exact matches created with a logical AND operation;<\/li><li>you can indicate that the rule is &#8220;soft&#8221;\/&#8221;preference&#8221; rather than a hard requirement, so if the scheduler can&#8217;t satisfy it, the pod will still be scheduled;<\/li><li>you can constrain against labels on other pods running on the node (or other topological domain), rather than against labels on the node itself, which allows rules about which pods can and cannot be co-located<\/li><\/ol>\n\n\n\n<p><strong>The affinity feature consists of two types of affinity<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>node affinity &#8211; Node affinity is like the existing nodeSelector (but with the first two benefits listed above)<\/li><li>inter-pod affinity\/anti-affinity &#8211; inter-pod affinity\/anti-affinity constrains against pod labels rather than node labels, as described in the all three item listed above.<\/li><\/ul>\n\n\n\n<p>These are fields in under Pod metadata and take automatic or user-defined metadata to dictate where to schedule pods. affinity differs from nodeSelector in the following ways:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Schedule a pod based on which other pods are or are not running on a node.<\/li><li>Request without requiring that a pod be run on a node.<\/li><li>Specify a set of allowable values instead of a single value requirement.<\/li><\/ul>\n\n\n\n<p><strong>Types of node affinity<\/strong><\/p>\n\n\n\n<p>There are currently two types of node affinity, called<\/p>\n\n\n\n<p>requiredDuringSchedulingIgnoredDuringExecution<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>hard rule<\/li><\/ul>\n\n\n\n<p>preferredDuringSchedulingIgnoredDuringExecution<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>soft rule<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-gallery columns-1 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\"><ul class=\"blocks-gallery-grid\"><li class=\"blocks-gallery-item\"><figure><img loading=\"lazy\" decoding=\"async\" width=\"1017\" height=\"139\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/Nodeaffinity-kubernetes.jpg\" alt=\"\" data-id=\"15720\" data-full-url=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/Nodeaffinity-kubernetes.jpg\" data-link=\"https:\/\/www.devopsschool.com\/blog\/?attachment_id=15720\" class=\"wp-image-15720\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/Nodeaffinity-kubernetes.jpg 1017w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/Nodeaffinity-kubernetes-300x41.jpg 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/Nodeaffinity-kubernetes-768x105.jpg 768w\" sizes=\"auto, (max-width: 1017px) 100vw, 1017px\" \/><\/figure><\/li><\/ul><\/figure>\n\n\n\n<p><strong>nodeAffinity example<\/strong><\/p>\n\n\n\n<p>Lets take the above example of deploying a nginx and a httpd pod, except we have a more complicated set of requirements:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>nginx cannot run on the same node as httpd<\/li><li>httpd should run on a node with the x-web:yes label, but can run anywhere.<\/li><li>nginx must run on a node with y-web:yes label and should fail if not.<\/li><\/ul>\n\n\n\n<script src=\"https:\/\/gist.github.com\/devops-school\/3da18faede22b18ac7013c404bc10740.js\"><\/script>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"536\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1-1024x536.png\" alt=\"\" class=\"wp-image-15733\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1-1024x536.png 1024w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1-300x157.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1-768x402.png 768w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1-1536x804.png 1536w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes1.png 1865w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"753\" height=\"416\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes2.png\" alt=\"\" class=\"wp-image-15734\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes2.png 753w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/node-affinity-kubernetes2-300x166.png 300w\" sizes=\"auto, (max-width: 753px) 100vw, 753px\" \/><\/figure>\n\n\n\n<p><strong>inter-pod affinity\/anti-affinity<\/strong><br>Inter-pod affinity and anti-affinity allow you to constrain which nodes your pod is eligible to be scheduled based on labels on pods that are already running on the node rather than based on labels on nodes.<\/p>\n\n\n\n<p><strong>An example of a pod that uses pod affinity<\/strong><\/p>\n\n\n\n<script src=\"https:\/\/gist.github.com\/devops-school\/f2a80cd487777d28d0f020cfab0eb4c1.js\"><\/script>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"765\" height=\"591\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/pod-affinity-kubernetes1.png\" alt=\"\" class=\"wp-image-15736\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/pod-affinity-kubernetes1.png 765w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2020\/07\/pod-affinity-kubernetes1-300x232.png 300w\" sizes=\"auto, (max-width: 765px) 100vw, 765px\" \/><\/figure>\n\n\n\n<p><strong>Reference<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/coreos.com\/fleet\/docs\/latest\/affinity.html\" target=\"_blank\" rel=\"noopener\">https:\/\/coreos.com\/fleet\/docs\/latest\/affinity.html<\/a><\/p>\n\n\n<div class=\"epyt-gallery\" data-currpage=\"1\" id=\"epyt_gallery_44439\"><figure class=\"wp-block-embed wp-block-embed-youtube is-type-video is-provider-youtube epyt-figure\"><div class=\"wp-block-embed__wrapper\"><iframe loading=\"lazy\"  id=\"_ytid_35120\"  width=\"760\" height=\"427\"  data-origwidth=\"760\" data-origheight=\"427\" src=\"https:\/\/www.youtube.com\/embed\/?enablejsapi=1&#038;autoplay=0&#038;cc_load_policy=0&#038;cc_lang_pref=&#038;iv_load_policy=1&#038;loop=0&#038;rel=1&#038;fs=1&#038;playsinline=0&#038;autohide=2&#038;theme=dark&#038;color=red&#038;controls=1&#038;disablekb=0&#038;\" class=\"__youtube_prefs__  no-lazyload\" title=\"YouTube player\"  data-epytgalleryid=\"epyt_gallery_44439\"  allow=\"fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><\/iframe><\/div><\/figure><div class=\"epyt-gallery-list\"><div>Sorry, there was a YouTube error.<\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>The Kubernetes scheduler can be constrained to place a pod on particular nodes using few different options. In your POD specification, there are many ways in which you declare a POD should be dedicated to specific nodes. Node Selector Node Affinity Pod Affinity aka inter-pod affinity\/anti-affinity Taints and Tolerations In this post, I am going&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","_joinchat":[],"footnotes":""},"categories":[1],"tags":[],"class_list":["post-15719","post","type-post","status-publish","format-standard","hentry","category-sql"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/15719","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=15719"}],"version-history":[{"count":12,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/15719\/revisions"}],"predecessor-version":[{"id":24688,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/15719\/revisions\/24688"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=15719"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=15719"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=15719"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}