{"id":649,"date":"2023-10-13T05:39:03","date_gmt":"2023-10-13T05:39:03","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=649"},"modified":"2023-10-13T05:39:03","modified_gmt":"2023-10-13T05:39:03","slug":"enable-feature-gates-kubeadm","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=649","title":{"rendered":"How to Enable Feature Gates in Kubeadm Setup [Tutorial]"},"content":{"rendered":"<p>In this blog, I explain the steps to enable feature gates in a Kubeadm cluster. Feature gates in Kubernetes let you enable alpha\/beta features in your Kubernetes cluster.<\/p>\n<p>For example, in Kubernetes Version 1.28, you can only enable a feature named &#8220;<strong>SidecarContainers<\/strong>&#8221; using the Feature Gate. You can check out all the available feature gates <a href=\"https:\/\/kubernetes.io\/docs\/reference\/command-line-tools-reference\/feature-gates\/?ref=devopscube.com\" rel=\"noreferrer noopener\">from here<\/a>.<\/p>\n<h2 id=\"enable-feature-gates-in-kubeadm\">Enable Feature Gates in Kubeadm<\/h2>\n<p>Feature gates need to be enabled when you initialize the Kubeadm cluster.<\/p>\n<p>The default <strong>kubeadm init<\/strong> command has a limitation in terms of enabling feature gates because there is only a limited set of feature gates supported by Kubeadm.<\/p>\n<p>To enable feature gates that are not supported by kubeadm init, you need to initialize the kubeadm cluster using the kubeadm configuration file.<\/p>\n<p>I assume you have minimum two nodes to test this setup. One master and one worker node.<\/p>\n<h2 id=\"install-crio-kubeadm-kubelet-and-kubectl\">Install CRIO, Kubeadm, Kubelet and kubectl<\/h2>\n<p>I assume you have at least two nodes to test this setup: one master and one worker node.<\/p>\n<p>First, you need to install the latest versions of container runtime, kubeadm, kubelet, and kubectl on all the nodes.<\/p>\n<blockquote><p><strong>Note:<\/strong> For detailed information on setting up Kubeadm, please read the <a href=\"https:\/\/devopscube.com\/setup-kubernetes-cluster-kubeadm\/\">Kubeadm Cluster Setup<\/a> Guide.<\/p><\/blockquote>\n<p>You can save the following as <strong><code>common.sh<\/code><\/strong> script. This script needs to be executed on master and worker node.<\/p>\n<p>Replace <strong>1.28.2-1.1<\/strong> with the required kubernetes version.<\/p>\n<pre><code>#!\/bin\/bash\n# Common setup for all servers (Control Plane and Nodes)\n\nset -euxo pipefail\n\n# Variable Declaration\n\nKUBERNETES_VERSION=\"1.28.2-1.1\"\n\n# disable swap\nsudo swapoff -a\n\n# keeps the swaf off during reboot\n(crontab -l 2&gt;\/dev\/null; echo \"@reboot \/sbin\/swapoff -a\") | crontab - || true\nsudo apt-get update -y\n\n\n# Install CRI-O Runtime\n\nOS=\"xUbuntu_22.04\"\n\nVERSION=\"1.28\"\n\n# Create the .conf file to load the modules at bootup\ncat &lt;&lt;EOF | sudo tee \/etc\/modules-load.d\/k8s.conf\noverlay\nbr_netfilter\nEOF\n\nsudo modprobe overlay\nsudo modprobe br_netfilter\n\n# sysctl params required by setup, params persist across reboots\ncat &lt;&lt;EOF | sudo tee \/etc\/sysctl.d\/k8s.conf\nnet.bridge.bridge-nf-call-iptables  = 1\nnet.bridge.bridge-nf-call-ip6tables = 1\nnet.ipv4.ip_forward                 = 1\nEOF\n\n# Apply sysctl params without reboot\nsudo sysctl --system\n\ncat &lt;&lt;EOF | sudo tee \/etc\/apt\/sources.list.d\/devel:kubic:libcontainers:stable.list\ndeb https:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable\/$OS\/ \/\nEOF\ncat &lt;&lt;EOF | sudo tee \/etc\/apt\/sources.list.d\/devel:kubic:libcontainers:stable:cri-o:$VERSION.list\ndeb http:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable:\/cri-o:\/$VERSION\/$OS\/ \/\nEOF\n\ncurl -L https:\/\/download.opensuse.org\/repositories\/devel:kubic:libcontainers:stable:cri-o:$VERSION\/$OS\/Release.key | sudo apt-key --keyring \/etc\/apt\/trusted.gpg.d\/libcontainers.gpg add -\ncurl -L https:\/\/download.opensuse.org\/repositories\/devel:\/kubic:\/libcontainers:\/stable\/$OS\/Release.key | sudo apt-key --keyring \/etc\/apt\/trusted.gpg.d\/libcontainers.gpg add -\n\nsudo apt-get update\nsudo apt-get install cri-o cri-o-runc -y\n\nsudo systemctl daemon-reload\nsudo systemctl enable crio --now\n\necho \"CRI runtime installed susccessfully\"\n\n# Install kubelet, kubectl and Kubeadm\n\nsudo apt-get update -y\nsudo apt-get install -y apt-transport-https ca-certificates curl\nsudo curl -fsSLo \/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg https:\/\/dl.k8s.io\/apt\/doc\/apt-key.gpg\n\necho \"deb [signed-by=\/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg] https:\/\/apt.kubernetes.io\/ kubernetes-xenial main\" | sudo tee \/etc\/apt\/sources.list.d\/kubernetes.list\nsudo apt-get update -y\nsudo apt-get install -y kubelet=\"$KUBERNETES_VERSION\" kubectl=\"$KUBERNETES_VERSION\" kubeadm=\"$KUBERNETES_VERSION\"\nsudo apt-get update -y\nsudo apt-mark hold kubelet kubeadm kubectl\n\nsudo apt-get install -y jq\n\nlocal_ip=\"$(ip --json addr show eth0 | jq -r '.[0].addr_info[] | select(.family == \"inet\") | .local')\"\ncat &gt; \/etc\/default\/kubelet &lt;&lt; EOF\nKUBELET_EXTRA_ARGS=--node-ip=$local_ip\nEOF<\/code><\/pre>\n<h2 id=\"kubeadm-config-with-feature-gates\">Kubeadm Config With Feature Gates<\/h2>\n<p>First, you need to ensure that the feature gate is supported by the Kubernetes version installed using Kubeadm.<\/p>\n<p>Here is an example Kubeadm config file where we&#8217;ve added the feature-gates option to the apiServer, controllerManager, scheduler, and KubeletConfiguration as extra arguments.<\/p>\n<p>Replace the parameters in bold with those that match your requirements and save the config as <code>kubeadm.config<\/code> on the control plane node.<\/p>\n<pre><code>apiVersion: kubeadm.k8s.io\/v1beta3\nkind: ClusterConfiguration\ncontrolPlaneEndpoint: \"35.92.162.218:6443\"\nnetworking:\n  podSubnet: 192.168.0.0\/16\napiServer:\n  extraArgs:\n    feature-gates: \"SidecarContainers=true\"\ncontrollerManager:\n  extraArgs:\n    feature-gates: \"SidecarContainers=true\"\nscheduler:\n  extraArgs:\n    feature-gates: \"SidecarContainers=true\"\n---\napiVersion: kubelet.config.k8s.io\/v1beta1\nkind: KubeletConfiguration\nfeatureGates:\n  SidecarContainers: true\n---\napiVersion: kubeadm.k8s.io\/v1beta3\nkind: InitConfiguration\nnodeRegistration:\n  name: \"controlplane\"\n  ignorePreflightErrors:\n  - Swap<\/code><\/pre>\n<p>You can enable <strong>multiple feature gates<\/strong> to the feature-gates parameter.<\/p>\n<h2 id=\"initialize-kubeadm-with-feature-gates\">Initialize Kubeadm With Feature gates<\/h2>\n<p>Once you have the Kubeadm Configuration, you can deploy the cluster with Feature gates using the following command.<\/p>\n<p>Ensure you are executing this in the Kubernetes control plane node.<\/p>\n<pre><code>kubeadm init --config=kubeadm.config<\/code><\/pre>\n<p>This will initialize the cluster with functionalities added through the feature gates.<\/p>\n<p>You can validate if the feature gates are enabled by checking the <a href=\"https:\/\/devopscube.com\/kubernetes-cluster-configurations\/\">Kuberentes cluster configurations<\/a>.<\/p>\n<p>For example, open the <strong><code>kube-apiserver.yaml<\/code><\/strong> manifest YAML present inside <strong><code>\/etc\/kubernetes\/manifests\/<\/code><\/strong> you will find the <strong>&#8211;feature-gates=SidecarContainers=true<\/strong> flag under spec as highlighted in the image below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-60-7.png\" class=\"kg-image\" alt=\"validating feature gates\" loading=\"lazy\" width=\"1842\" height=\"1276\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-60-7.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-60-7.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/image-60-7.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-60-7.png 1842w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"join-worker-nodes\">Join Worker Nodes<\/h2>\n<p>Once the initialization is done, you can join the worker nodes to the control plane using the join command.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-59-10.png\" class=\"kg-image\" alt=\"kubeadm join command for worker nodes\" loading=\"lazy\" width=\"800\" height=\"622\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-59-10.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-59-10.png 800w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>By enabling feature gates, you can test features added to the latest Kubernetes versions.<\/p>\n<p>If you encounter any issues during the setup, feel free to drop a comment below, and we&#8217;ll take a look.<\/p>\n<p>If you are starting your kubernetes journey, check out our 40+ <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\">Kubernetes tutorials.<\/a><\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/enable-feature-gates-kubeadm\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Enable Feature Gates in Kubeadm Setup [Tutorial] \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/enable-feature-gates-kubeadm\/<\/p>\n","protected":false},"author":1,"featured_media":650,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-649","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=649"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/649\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/650"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}