---
title: "Update certificates for system components in a Managed Kubernetes cluster"
sidebar_label: "Update certificates for system components"
sidebar_position: 7
description: "How to update certificates in the Control panel and configure updates via a Service Account Token"
---

import Formbricks from '@theme/MDXComponents/Formbricks';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import { TabItemLabel } from '@selectel/docux/components';

# Update certificates for system components in a Managed Kubernetes cluster

For [Kubernetes system components](https://kubernetes.io/ru/docs/concepts/overview/components/) to interact, valid certificates are required. They are updated automatically every 30 days. If an error occurs during certificate renewal, you can [update certificates in the Control Panel](#update-certificates-when-error-occurs) or via the [Managed Kubernetes API](/api/managed-kubernetes/).

Information about certificate updates is reflected in the [cluster logs](/managed-kubernetes/clusters/logs.mdx).

The kubeconfig file changes with every certificate update, so you must [reconnect](/managed-kubernetes/clusters/connect-to-cluster.mdx) to the cluster. To avoid reconnecting, [configure updates via ServiceAccount Token](#configure-certificate-update-via-serviceaccount-token).

## Update certificates when an error occurs \{#update-certificates-when-error-occurs}

If an error `ROTATE CERTS = ERROR` occurred during the automatic certificate update, you can update the certificates in the Control panel or via the [Managed Kubernetes API](/api/managed-kubernetes/).

1. In the [Control panel](https://my.selectel.ru/mks/), click **Products** in the top menu and select **Managed Kubernetes**.
2. In the **Clusters** section, open the cluster page → **Settings** tab.
3. In the **Cluster access** block, click **Update certificates**.
4. [Reconnect to the cluster](/managed-kubernetes/clusters/connect-to-cluster.mdx).

## Configure certificate updates via ServiceAccount Token \{#configure-certificate-update-via-serviceaccount-token}

ServiceAccount Token is a method for authorizing in the Kubernetes API. It allows you to avoid updating the kubeconfig file after each certificate update.

The process of obtaining a ServiceAccount Token depends on the Kubernetes version:

* [for Kubernetes version 1.23 and lower](#for-kubernetes-version-123-and-lower);
* [for Kubernetes version 1.24 and higher](#for-kubernetes-version-124-and-higher).

### For Kubernetes version 1.23 and lower \{#for-kubernetes-version-123-and-lower}

<Tabs queryString="for-kubernetes-version-123-and-lower">
  <TabItem value="Linux" default>
    <TabItemLabel>
      Linux
    </TabItemLabel>

    1. Create a ServiceAccount:

       ```bash
       kubectl -n kube-system create serviceaccount <serviceaccount_name>
       ```

       Specify `<serviceaccount_name>` — the name of the service account.

    2. Create a ClusterRoleBinding (a group for the new user) and add a role with administrator rights (cluster-admin):

       ```bash
       kubectl create clusterrolebinding <clusterrolebinding_name> --clusterrole=cluster-admin --serviceaccount=kube-system:<serviceaccount_name>
       ```

       Specify `<clusterrolebinding_name>` — the name of the group for the new user.

    3. Add the name of the created ServiceAccount secret that stores the token to the `TOKENNAME` environment variable:

       ```bash
       export TOKENNAME=$(kubectl -n kube-system get serviceaccount/<serviceaccount_name> -o jsonpath='{.secrets[0].name}')
       ```

    4. Add the decoded token from the secret to the `TOKEN` environment variable:

       ```bash
       export TOKEN=$(kubectl -n kube-system get secret $TOKENNAME -o jsonpath='{.data.token}' | base64 --decode)
       ```

    5. Check if the token works — make a request to the Kubernetes API with the token in the header:

       ```bash
       curl -k -H "Authorization: Bearer $TOKEN" -X GET "https://<kube_api_ip>:6443/api/v1/nodes" | json_pp
       ```

       Specify `<kube_api_ip>` — the cluster IP address in the Control panel.

    6. Add the ServiceAccount to the kubeconfig file:

       ```bash
       kubectl config set-credentials <serviceaccount_name> --token=$TOKEN
       ```

    7. Switch the context:

       ```bash
       kubectl config set-context --current --user=<serviceaccount_name>
       ```

    8. Check if it works — make any request to the Kubernetes API. For example, request a list of cluster nodes:

       ```bash
       kubectl get nodes
       ```

    9. The updated kubeconfig file will be in the home directory `$HOME/.kube/config`.
  </TabItem>

  <TabItem value="windows">
    <TabItemLabel>
      Windows
    </TabItemLabel>

    1. Run PowerShell as an administrator.

    2. Create a ServiceAccount:

       ```bash
       kubectl -n kube-system create serviceaccount <serviceaccount_name>
       ```

       Specify `<serviceaccount_name>` — the name of the service account.

    3. Create a ClusterRoleBinding (a group for the new user) and add a role with administrator rights (cluster-admin):

       ```bash
       kubectl create clusterrolebinding <clusterrolebinding_name> --clusterrole=cluster-admin --serviceaccount=kube-system:<serviceaccount_name>
       ```

       Specify `<clusterrolebinding_name>` — the name of the group for the new user.

    4. Get the name of the secret of the created ServiceAccount that stores the token:

       ```bash
       $env:token_name = kubectl -n kube-system get serviceaccount/<serviceaccount_name> -o jsonpath='{.secrets[0].name}'
       ```

    5. Add the decoded token from the secret to the `token` variable:

       ```bash
       $env:token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String((kubectl -n kube-system get secret $token_name -o jsonpath='{.data.token}')))
       ```

    6. Add the ServiceAccount to the kubeconfig file:

       ```bash
       kubectl config set-credentials <serviceaccount_name> --token=$token
       ```

    7. Switch the context:

       ```bash
       kubectl config set-context --current --user=<serviceaccount_name>
       ```

    8. Check if it works — make any request to the Kubernetes API. For example, request a list of cluster nodes:

       ```bash
       kubectl get nodes
       ```

    9. The updated kubeconfig file will be in the home directory `$env:USERPROFILE/.kube/config`.
  </TabItem>
</Tabs>

### For Kubernetes version 1.24 and higher \{#for-kubernetes-version-124-and-higher}

<Tabs queryString="for-kubernetes-version-124-and-higher">
  <TabItem value="Linux" default>
    <TabItemLabel>
      Linux
    </TabItemLabel>

    1. Create a ServiceAccount:

       ```bash
       kubectl -n kube-system create serviceaccount <serviceaccount_name>
       ```

       Specify `<serviceaccount_name>` — the name of the service account.

    2. Create a ClusterRoleBinding (a group for the new user) and add a role with administrator rights (cluster-admin):

       ```bash
       kubectl create clusterrolebinding <clusterrolebinding_name> --clusterrole=cluster-admin --serviceaccount=kube-system:<serviceaccount_name>
       ```

       Specify `<clusterrolebinding_name>` — the name of the group for the new user.

    3. Get the name of the secret of the created ServiceAccount that stores the token:

       ```yaml
       kubectl -n kube-system apply -f - <<EOF
       apiVersion: v1
       kind: Secret
       metadata:
         name: <serviceaccount_name>-token
         annotations:
           kubernetes.io/service-account.name: <serviceaccount_name>
       type: kubernetes.io/service-account-token
       EOF
       ```

    4. Add the decoded token from the secret to the `TOKEN` environment variable:

       ```bash
       export TOKEN=$(kubectl -n kube-system get secret <serviceaccount_name>-token -o jsonpath='{.data.token}' | base64 --decode)
       ```

    5. Check if the token works — make a request to the Kubernetes API with the token in the header:

       ```bash
       curl -k -H "Authorization: Bearer $TOKEN" -X GET "https://<kube_api_ip>:6443/api/v1/nodes" | json_pp
       ```

       Specify `<kube_api_ip>` — the cluster IP address in the Control panel.

    6. Add the ServiceAccount to the kubeconfig file:

       ```bash
       kubectl config set-credentials <serviceaccount_name> --token=$TOKEN
       ```

    7. Switch the context:

       ```bash
       kubectl config set-context --current --user=<serviceaccount_name>
       ```

    8. Check if it works — make any request to the Kubernetes API. For example, request a list of cluster nodes:

       ```bash
       kubectl get nodes
       ```

    9. The updated kubeconfig file will be in the home directory `$HOME/.kube/config`.
  </TabItem>

  <TabItem value="windows">
    <TabItemLabel>
      Windows
    </TabItemLabel>

    1. Run PowerShell as an administrator.

    2. Create a ServiceAccount:

       ```bash
       kubectl -n kube-system create serviceaccount <serviceaccount_name>
       ```

       Specify `<serviceaccount_name>` — the name of the service account.

    3. Create a ClusterRoleBinding (a group for the new user) and add a role with administrator rights (cluster-admin):

       ```bash
       kubectl create clusterrolebinding <clusterrolebinding_name> --clusterrole=cluster-admin --serviceaccount=kube-system:<serviceaccount_name>
       ```

       Specify `<clusterrolebinding_name>` — the name of the group for the new user.

    4. Get the name of the secret of the created ServiceAccount that stores the token:

       ```yaml
       @"
       apiVersion: v1
       kind: Secret
       metadata:
         name: <serviceaccount_name>-token
         annotations:
           kubernetes.io/service-account.name: <serviceaccount_name>
       type: kubernetes.io/service-account-token
       "@ | kubectl -n kube-system apply -f -
       ```

    5. Add the decoded token from the secret to the `TOKEN` environment variable:

       ```bash
       $env:token = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String((kubectl -n kube-system get secret <serviceaccount_name>-token -o jsonpath='{.data.token}')))
       ```

    6. Add the ServiceAccount to the kubeconfig file:

       ```bash
       kubectl config set-credentials <serviceaccount_name> --token=$token
       ```

    7. Switch the context:

       ```bash
       kubectl config set-context --current --user=<serviceaccount_name>
       ```

    8. Check if it works — make any request to the Kubernetes API. For example, request a list of cluster nodes:

       ```bash
       kubectl get nodes
       ```

    9. The updated kubeconfig file will be in the home directory `$env:USERPROFILE/.kube/config`.
  </TabItem>
</Tabs>

<Formbricks />
