<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ham</title>
    <description>The latest articles on DEV Community by Ham (@hatr0).</description>
    <link>https://dev.to/hatr0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1207273%2Faa317d9e-25d9-4b46-b3c2-3b368bd92b60.png</url>
      <title>DEV Community: Ham</title>
      <link>https://dev.to/hatr0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hatr0"/>
    <language>en</language>
    <item>
      <title>Fixing Expired Certificates In Kubernetes for Worker Nodes</title>
      <dc:creator>Ham</dc:creator>
      <pubDate>Sat, 31 Oct 2026 09:53:55 +0000</pubDate>
      <link>https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-for-worker-nodes-42bm</link>
      <guid>https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-for-worker-nodes-42bm</guid>
      <description>&lt;p&gt;By default, when you setup your Kubernetes cluster, the certificates expires after one year. &lt;/p&gt;

&lt;p&gt;The process to check is exactly like the process explained in &lt;a href="https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-1oe2"&gt;https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-1oe2&lt;/a&gt;.&lt;br&gt;
I have copied and paste all the needed commands here so no need to visit the post. &lt;/p&gt;

&lt;p&gt;From the control plane node, if you issue the following command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubectl get nodes&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You'll notice some of your worker nodes have a &lt;strong&gt;STATUS&lt;/strong&gt; of &lt;strong&gt;NotReady&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftiphjfdww6fn4tvsuhfj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftiphjfdww6fn4tvsuhfj.jpg" alt="kubectl get nodes" width="461" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's do some further checking. SSH to one of the worker nodes that has a status of NotReady. &lt;/p&gt;

&lt;p&gt;The below commands requires 'root' privileged, so if you are login as non-root, you will need to prepend &lt;code&gt;sudo&lt;/code&gt; before the commands. &lt;/p&gt;

&lt;p&gt;Check your kubelet service, is it failing to start (&lt;code&gt;systemctl status kubelet&lt;/code&gt;)?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzpr03usdfhpc8kdwy4pr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzpr03usdfhpc8kdwy4pr.jpg" alt="systemctl status kubelet" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's check logs related with kubelet (&lt;code&gt;journalctl | grep kubelet&lt;/code&gt;), you'll noticed the belong error messages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F53w2h9xtjd3tlahsln5w.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F53w2h9xtjd3tlahsln5w.jpg" alt="journalctl kubectl logs" width="796" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see an entry about bootstrap client certificate is expired. &lt;/p&gt;

&lt;p&gt;Since the kubelet service on worker nodes talks to control plane, an expired license will prevent the kubelet from authenticating with the API server. &lt;/p&gt;

&lt;p&gt;Let's verify our issue with the 'openssl' command.&lt;/p&gt;

&lt;p&gt;Let's check kubelet client certificate with the following command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -text | grep 'Not After'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Not After : Feb 16 00:38:07 2023 GMT &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the date shown is in the past, the certificate has expired. &lt;/p&gt;
&lt;h2&gt;
  
  
  Let's renew certificates.
&lt;/h2&gt;

&lt;p&gt;If your cluster has more than one worker node, be sure to check certificate expiration with the command above on all nodes.  If certificate has expired, run the following commands on all expired worker nodes in the cluster.&lt;/p&gt;

&lt;p&gt;First, let's backup our certificates just in case we need them.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cp /etc/kubernetes/kubelet.conf  /etc/kubernetes/kubelet.conf.backup&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cp -r /var/lib/kubelet/pki /var/lib/kubelet/pki.backup&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let's remove the expired certificates&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rm /etc/kubernetes/kubelet.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rm /var/lib/kubelet/pki/kubelet-client*&lt;/code&gt; - Note: Wildcard might not work due to security restrictions, so delete each file individually. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After you delete the expired certificates, let's generate a new kubelet configuration. &lt;/p&gt;

&lt;p&gt;On a working control plane node, let's first create a working &lt;strong&gt;config&lt;/strong&gt; file since that is needed to create a new kubelet configuration file. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file name temp-config.yaml&lt;/li&gt;
&lt;li&gt;Add the following to the file and save the file.
You can verify and match the entries with the current running cluster with the following command:
&lt;code&gt;kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}"&lt;/code&gt;
This information can be found at &lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/" rel="noopener noreferrer"&gt;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Temporary config.yaml file to generate new kubelet configuration file&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kubeadm.k8s.io/v1beta3&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterConfiguration&lt;/span&gt;
&lt;span class="c1"&gt;# Cluster name in the kubeconfig &lt;/span&gt;
&lt;span class="na"&gt;clusterName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kubernetes"&lt;/span&gt;
&lt;span class="c1"&gt;# The server IP/DNS name of the cluster in the kubeconfig&lt;/span&gt;
&lt;span class="na"&gt;controlPlaneEndpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IP&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DNS&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:6443"&lt;/span&gt;
&lt;span class="c1"&gt;# Cluster CA key and certificate will be loaded from this local directory&lt;/span&gt;
&lt;span class="na"&gt;certficatesDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/etc/kubernetes/pki"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now with the config.yaml file created, let's create the configuration file, substitute  with the actual hostname of the worker node you are fixing, execute the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;worker-node-name&amp;gt;
kubeadm kubeconfig user &lt;span class="nt"&gt;--org&lt;/span&gt; system:nodes &lt;span class="nt"&gt;--client-name&lt;/span&gt; system:node:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;NODE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--config&lt;/span&gt; temp-config.yaml &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; kubelet.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the kubelet.conf file is generated, let's transfer this to the worker node.  Substitute  with the worker node IP or DNS name you are fixing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp kubelet.conf &amp;lt;worker-node&amp;gt;:/tmp/kubelet.conf
ssh &amp;lt;worker-node&amp;gt;
&lt;span class="nb"&gt;mv&lt;/span&gt; /tmp/kubelet.conf /etc/kubernetes/kubelet.conf
&lt;span class="nb"&gt;chown &lt;/span&gt;root:root /etc/kubernetes/kubelet.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now still logged in on worker node, restart the kubectl service&lt;br&gt;
&lt;code&gt;systemctl restart kubelet&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Verify by checking kubelet service and issue kubectl commands. &lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>certificates</category>
      <category>workernodes</category>
    </item>
    <item>
      <title>Getting Cilium to work on Ubuntu Cloud Image</title>
      <dc:creator>Ham</dc:creator>
      <pubDate>Fri, 03 Jan 2025 08:07:56 +0000</pubDate>
      <link>https://dev.to/hatr0/getting-cilium-to-work-on-ubuntu-cloud-image-3843</link>
      <guid>https://dev.to/hatr0/getting-cilium-to-work-on-ubuntu-cloud-image-3843</guid>
      <description>&lt;p&gt;How to get Cilium working on Ubuntu Cloud Images Focal (20.04) or Jammy (22.04). &lt;/p&gt;

&lt;p&gt;If you are running one of the Ubuntu Cloud Images and you are trying to install Cilium as your CNI network plugin on your Kubernetes cluster. You might have noticed that you get CrashLoopBackOff from your cilium pods when issuing a &lt;code&gt;kubectl get pods -n kube-system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvg27jf7brg2ti2ktn8r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvg27jf7brg2ti2ktn8r.png" alt="kubectl get pods output" width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon further troubleshooting on the problem pod with a &lt;code&gt;kubectl logs cilium-jgcdm -n kube-system&lt;/code&gt; you might see the below messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9rbdwivnnhovfviy3nv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm9rbdwivnnhovfviy3nv.png" alt="cilium pod logs display" width="800" height="34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1tv334m2wroi6f519im.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1tv334m2wroi6f519im.png" alt="cilium pod logs daemon qdisk" width="800" height="32"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a very good chance you are missing some kernel configuration options. Have a look at &lt;a href="https://docs.cilium.io/en/stable/operations/system_requirements/#linux-kernel" rel="noopener noreferrer"&gt;https://docs.cilium.io/en/stable/operations/system_requirements/#linux-kernel&lt;/a&gt; for more information. &lt;/p&gt;

&lt;p&gt;The base requirements are:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9us5gkt3ni8yf68nvjhc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9us5gkt3ni8yf68nvjhc.png" alt="cilium required kernel options" width="468" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On a Ubuntu system running 20.04, you can check your kernel configurations with:&lt;br&gt;
&lt;code&gt;cat /lib/modules/$(uname -r)/build/.config&lt;/code&gt; - Note: if you are not running as root, prepend &lt;code&gt;sudo&lt;/code&gt; before  the command. &lt;/p&gt;

&lt;p&gt;You can look for specific config options by prepending a pipe to grep:&lt;br&gt;
&lt;code&gt;cat /lib/modules/$(uname -r)/build/.config | grep -i config_bpf_jit&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;After checking, you will noticed that certain options are not enabled. To solve, let's replace our kernel variant with the 'generic' version. If not running as root, prepend &lt;code&gt;sudo&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt update &amp;amp;&amp;amp; apt install linux-generic&lt;/code&gt; or &lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install linux-generic -y&lt;/code&gt; if not running as root. &lt;/p&gt;

&lt;p&gt;Now let's build initramfs for the kernel. You will want to use the generic kernel version that was installed, you should see the version from the install screen. You can also check under '/boot' directory with the command &lt;code&gt;ls /boot&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Note: at the time of this writing, '5.4.0-204-generic' is the installed kernel version. &lt;br&gt;
&lt;code&gt;update-initramfs -u -k 5.4.0-204-generic&lt;/code&gt; or &lt;code&gt;sudo update-initramfs -u -k 5.4.0-204-generic&lt;/code&gt; for non-root user. &lt;/p&gt;

&lt;p&gt;Note: If you want to remove 'linux-kvm' variant, issue&lt;br&gt;
&lt;code&gt;sudo apt purge linux-kvm&lt;/code&gt;&lt;br&gt;
If you plan to keep the 'linux-kvm' kernel around, don't issue the apt purge command and move any files ending in '-kvm' in the /boot directory to a different folder.&lt;br&gt;
&lt;code&gt;mkdir /boot/kvm-kernel&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mv /boot/*-kvm /boot/kvm-kernel/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, let's update grub&lt;br&gt;
&lt;code&gt;update-grub&lt;/code&gt; or &lt;code&gt;sudo update-grub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Reboot the system&lt;br&gt;
&lt;code&gt;reboot&lt;/code&gt; or &lt;code&gt;sudo reboot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Repeat the above steps for each of the nodes you have in the cluster. &lt;/p&gt;

&lt;p&gt;After installing 'generic' kernel and rebooting, check your cilium pods again and they all should be running. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get pods -n kube-system -owide&lt;/code&gt; - the '-owide' option will show which node the pods are running on. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4d0adb8ckdz157mz824.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4d0adb8ckdz157mz824.png" alt="kubectl info with cilium pod running state" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cilium</category>
      <category>ubuntu</category>
      <category>cloud</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Fixing Expired Certificates In Kubernetes</title>
      <dc:creator>Ham</dc:creator>
      <pubDate>Fri, 03 Jan 2025 06:20:32 +0000</pubDate>
      <link>https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-1oe2</link>
      <guid>https://dev.to/hatr0/fixing-expired-certificates-in-kubernetes-1oe2</guid>
      <description>&lt;p&gt;By default, when you setup your Kubernetes cluster, the certificates expires after one year. &lt;/p&gt;

&lt;p&gt;If it's been a while since you started up your Kubernetes cluster and you try to issue kubectl commands and notice connection refused errors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwluxgnetlc2tgm1fdyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwluxgnetlc2tgm1fdyz.png" alt="kubectl connection refused" width="800" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The below commands requires 'root' privileged, so if you are login as non-root, you will need to prepend &lt;code&gt;sudo&lt;/code&gt; before the commands. &lt;/p&gt;

&lt;p&gt;Troubleshooting further, you noticed that your kubelet service is failing to start (&lt;code&gt;systemctl status kubelet&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Upon checking logs related with kubelet (&lt;code&gt;journalctl | grep kubelet&lt;/code&gt;), you noticed the belong error messages. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsqer7i1zyou0monp1dl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhsqer7i1zyou0monp1dl.png" alt="journalctl kubelet errors" width="796" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are several ways to verify our issue, let's issue &lt;code&gt;kubeadm certs check-expiration&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhfhm4xbtel0x098gbm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvhfhm4xbtel0x098gbm8.png" alt="kubeadm certs check" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bingo! &lt;/p&gt;

&lt;p&gt;An alternative to using kubeadm would be to use 'openssl' command.&lt;br&gt;
Let's check a specific certificate, in this case the API server certificate: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep 'Not After'"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Not After : Nov 07 01:16:00 2024 GMT&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As we see, the API server certificate has expired, you can also check the other certificates to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/etc/kubernetes/pki/front-proxy-client.crt&lt;/li&gt;
&lt;li&gt;/etc/kubernetes/pki/etcd/peer.crt&lt;/li&gt;
&lt;li&gt;/etc/kubernetes/pki/etcd/server.crt&lt;/li&gt;
&lt;li&gt;/etc/kubernetes/pki/etcd/healthcheck-client.crt&lt;/li&gt;
&lt;li&gt;/etc/kubernetes/pki/apiserver-etcd-client.crt&lt;/li&gt;
&lt;li&gt;/etc/kubernetes/pki/apiserver-kubelet-client.crt&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Let's renew certificates.
&lt;/h2&gt;

&lt;p&gt;If your cluster has more than one control-plane node, be sure to run the following commands on all control-plane nodes in the cluster.&lt;/p&gt;

&lt;p&gt;First, let's backup our certificates just in case we need them.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cp -R /etc/kubernetes/pki  /etc/kubernetes/pki.backup&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Manually renew certificates to fix our issues.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Now let's renew our certificates with&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubeadm certs renew all&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will renew all certificates, if only a specific certificate has expired, you can renew the specific certificate with the following command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubeadm certs renew &amp;lt;specific server/service&amp;gt;&lt;/code&gt; - where  would be for example, &lt;code&gt;apiserver&lt;/code&gt;, so &lt;strong&gt;kubeadm certs renew apiserver&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify new certificate installed correctly. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubeadm certs check-expiration&lt;/code&gt; or use &lt;code&gt;openssl&lt;/code&gt; command from above &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Restart kubelet service&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;systemctl restart kubelet&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the renew process is complete, we will need to restart all the control plane pods. One way to restart is moving it's manifest file out and wait for for about 20 seconds before moving the file back in to the 'manifests' folder. This will will recreate the Pod to use the new certificates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cd /etc/kubernetes/manifests&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mv *.yaml ..&lt;/code&gt;  - Move all yaml files one level up&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mv ../*.yaml .&lt;/code&gt; - After 20 seconds, move all yaml file back to current directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copy the administrator certificates &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sudo chown $(id -u):$(id -g) $HOME/.kube/config&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should get your cluster running again. You can verify with &lt;code&gt;kubectl get pods&lt;/code&gt; and not get an error.  &lt;/p&gt;

&lt;p&gt;&lt;u&gt;&lt;strong&gt;Update kubeconfig files - only if you renew certificates individually&lt;/strong&gt;&lt;/u&gt;&lt;/p&gt;

&lt;p&gt;If you updated individual certificates and after restarting kubelet service, things are still not working, you might need to update kubeconfig files. Do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubeadm init phase kubeconfig admin&lt;/code&gt; - this will update &lt;em&gt;admin&lt;/em&gt; user (admin.conf).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubeadm init phase kubeconfig controller-manager&lt;/code&gt; - this will update controller manager.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubeadm init phase kubeconfig scheduler&lt;/code&gt; - this will update the scheduler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this still doesn't work, before continuing to troubleshoot, reboot the system to make sure all services are restarted correctly. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sudo reboot&lt;/code&gt; or &lt;code&gt;sudo shutdown -r now&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl status kubelet&lt;/code&gt; - After reboot, login and check status again. if fail, view section on "Additional Things To Do..." below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Renew automatically via Kubernetes Upgrade&lt;/strong&gt;&lt;br&gt;
If you also need to update your Kubernetes version, you can apply the upgrade and all certificates will get renewed.&lt;/p&gt;

&lt;p&gt;Let's run the following command to check current version and what available upgrades version.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubeadm upgrade plan&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Find the version to upgrade to and issue the following to upgrade.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubeadm upgrade apply &amp;lt;version&amp;gt;&lt;/code&gt; - substitute the  with the version number to update to. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Additional Things To Do If The Steps Above Doesn't Work
&lt;/h2&gt;

&lt;p&gt;If for some reason the above doesn't work, you will need to do the following. Make a backup of /etc/kubernetes/pki/&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cp -R /etc/kubernetes/pki /etc/kubernetes/pki-backup&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Delete the following files from /etc/kubernetes/pki&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rm apiserver.crt \ 
apiserver-etcd-client.key\ 
apiserver-kubelet-client.crt\ 
front-proxy-ca.crt\ 
front-proxy-client.crt\ 
front-proxy-client.key\
front-proxy-ca.key\ 
apiserver-kubelet-client.key\ 
apiserver.key\ 
apiserver-etcd-client.crt&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remove all .crt and .key files from /etc/kubernetes/pki/etcd&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rm /etc/kubernetes/pki/etcd/*.crt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rm /etc/kubernetes/pki/etcd/*.key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then create certs with&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubeadm init phase certs all --apiserver-advertise-address &amp;lt;IP&amp;gt;&lt;/code&gt; --substitute your cluster IP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Backup\Move conf files from /etc/kubernetes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mkdir conf-backup&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mv admin.conf\ controller-manager.conf\ kubelet.conf\ scheduler.conf /etc/kubernetes/conf-backup/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create new conf files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kubeadm init phase kubeconfig all&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, restart kubelet service or reboot system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;systemctl restart kubelet&lt;/code&gt; or &lt;code&gt;reboot&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>certificates</category>
    </item>
  </channel>
</rss>
