# Connecting to a node over SSH

To connect to a [Managed Service for Kubernetes cluster](../concepts/index.md#kubernetes-cluster) [node](../concepts/index.md#node-group) over SSH:
* Add the public key to the metadata when [creating a Managed Service for Kubernetes node group](node-group/node-group-create.md).

  {% note info %}

  SSH connection using a login and password is disabled by default on Linux images that are used on Managed Service for Kubernetes nodes.

  {% endnote %}

* [Configure security groups](connect/security-groups.md) for the Managed Service for Kubernetes cluster.

  {% note warning %}

  Security group settings may block connection to the Managed Service for Kubernetes cluster.

  {% endnote %}

For more information, see [Connecting to a VM over SSH](../../compute/operations/vm-connect/ssh.md).

Individual nodes in node groups are Yandex Compute Cloud virtual machines with automatically generated names. To configure nodes, follow the steps below or [other node group management guides](index.md#node-group).

{% note alert %}

Do not change node VM settings, including names, network interfaces, and SSH keys, using the Compute Cloud interfaces or SSH connections to the VM.

This can disrupt the operation of individual nodes, node groups, and the whole Managed Service for Kubernetes cluster.

{% endnote %}

## Create SSH key pairs {#creating-ssh-keys}

Prepare the keys to use with your Managed Service for Kubernetes cluster node. Follow these steps:

{% list tabs group=operating_system %}

- Linux/macOS {#linux-macos}

  1. Open the terminal.
  1. Use the `ssh-keygen` command to create a new key:

     ```bash
     ssh-keygen -t ed25519
     ```

     After running this command, the system will prompt you to specify the names of files to store the keys and enter the password for the private key. The default name is `id_ed25519`. Keys are created in the `~/.ssh` directory.

     The public part of the key will be saved to a file named `<key_name>.pub`.

- Windows 10/11 {#windows}

  1. Run `cmd.exe` or `powershell.exe`.
  1. Use the `ssh-keygen` command to create a new key. Run this command:

     ```bash
     ssh-keygen -t ed25519
     ```

     After running this command, the system will prompt you to specify the names of files to store the keys and enter the password for the private key. The default name is `id_ed25519`. Keys are created in the `C:\Users\<username>\.ssh\` directory.

     The public part of the key will be saved to a file named `<key_name>.pub`.

- Windows 7/8 {#windows7-8}

  Create keys using PuTTY:
  1. [Download](https://www.putty.org) and install PuTTY.
  1. Add the folder with PuTTY to the `PATH` variable:

      1. Click **Start** and type **Change system environment variables** in the Windows search bar.
      1. Click **Environment Variables...** at the bottom right.
      1. In the window that opens, find the `PATH` parameter and click **Edit**.
      1. Add your folder path to the list.
      1. Click **OK**.

  1. Launch the PuTTYgen application.
  1. Select **Ed25519** as the pair type to generate. Click **Generate** and move the cursor in the field above it until the key is created.

     ![ssh_generate_key](../../_assets/compute/ssh-putty/ssh_generate_key.png)

  1. In **Key passphrase**, enter a strong password. Enter it again in the field below.
  1. Click **Save private key** and save the private key. Do not share its key phrase with anyone.
  1. Save the key in a text file in a single line. To do this, copy the public key from the text field and paste it to a text file named `id_ed25519.pub`.

{% endlist %}

## Convert the public key to the metadata format {#key-format}

Your username and public key are the credentials for connecting to the Managed Service for Kubernetes cluster nodes over SSH. These credentials are provided using metadata in a specific format.

The public key [you created earlier](#creating-ssh-keys) has the following format:

```text
<key_type> <public_key_body> <optional_comment>
```

Here is an example:

> ```text
> ssh-ed25519 AAAAB3NzaC***********lP1ww ed25519-key-20190412
> ```

Create a file with credentials for connecting over SSH in the following format:

```text
<username>:<key_type> <public_key_body> <username>
```

Here is an example:

> ```text
> testuser:ssh-ed25519 AAAAB3NzaC***********lP1ww testuser
> ```

This format is suitable for creating and updating a Managed Service for Kubernetes node group using the CLI, Terraform, and API interfaces, and for updating a node group using the management console. When creating a node group, separate **Login** and **SSH key** fields are used in the management console.

You can provide credentials for multiple users in one file.

Here is an example:

> ```text
> testuser1:ssh-ed25519 AAAAB3NzaC***********lP1ww testuser1
> testuser2:ssh-ed25519 ONEMOREkey***********avEHw testuser2
> ```

## Create a node group and add the public key {#node-create}

{% list tabs group=instructions %}

- Management console {#console}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Managed Service for&nbsp;Kubernetes**.
  1. Select Managed Service for Kubernetes.
  1. In the left-hand panel, select **Node management**.
  1. Click **Create a node group**.
  1. Set the node group parameters.
  1. Under **Access**, specify the credentials to access the Managed Service for Kubernetes node:
      * In the **Login** field, enter the username.
      * In the **SSH key** field, paste the contents of the public key file.
  1. Click **Create**.

- CLI {#cli}

  Metadata with credentials for connecting over SSH is provided to the Managed Service for Kubernetes node group as `key=value` pairs.

  {% note warning %}
  
  The `user-data` VM metadata key is not supported for user data transmission. Use the `ssh-keys` key to provide parameters for SSH connections.
  
  {% endnote %}

  If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

  The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

  To create a Managed Service for Kubernetes node group and provide user credentials for connecting over SSH, run this command:

  ```bash
  yc managed-kubernetes node-group create \
    --name <node_group_name> \
    --cluster-name <cluster_name> \
    --fixed-size <number_of_nodes_in_group> \
    --network-interface security-group-ids=[<list_of_security_groups>],subnets=<subnet_name>,ipv4-address=nat \
    --metadata-from-file ssh-keys=<path_to_credentials_file>
  ```

  Where `--metadata-from-file` is the parameter to provide metadata to the node group as `key=value` pairs. In `ssh-keys`, specify the path to the file with credentials for connecting over SSH.

- Terraform {#tf}

  Metadata with credentials for connecting over SSH is provided to the Managed Service for Kubernetes node group as `key=value` pairs.

  {% note warning %}
  
  The `user-data` VM metadata key is not supported for user data transmission. Use the `ssh-keys` key to provide parameters for SSH connections.
  
  {% endnote %}

  1. Create a Terraform configuration file describing the Managed Service for Kubernetes node group by following the steps described in [Creating a node group](node-group/node-group-create.md).

  1. In the node group description, set the `ssh-keys` metadata key value for the `instance_template.metadata` parameter:

      ```hcl
      resource "yandex_kubernetes_node_group" "<node_group_name>" {
        cluster_id = yandex_kubernetes_cluster.<cluster_name>.id
        ...
        instance_template {
          metadata = {
            "ssh-keys" = file("<path_to_credentials_file>")
            ...
          }
          ...
        }
        ...
      }
      ```

  1. Make sure the configuration files are correct.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm resource changes.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

      {% note warning "Timeouts" %}
      
      The Terraform provider sets time limits for operations with Managed Service for Kubernetes cluster node groups:
      
      * Creating and editing: 60 minutes.
      * Deleting: 20 minutes.
      
      Operations in excess of this time will be interrupted.
      
      {% cut "How do I modify these limits?" %}
      
      Add the `timeouts` section to the cluster node group description, e.g.:
      
      ```hcl
      resource "yandex_kubernetes_node_group" "<node_group_name>" {
        ...
        timeouts {
          create = "1h30m"
          update = "1h30m"
          delete = "60m"
        }
      }
      ```
      
      {% endcut %}
      
      {% endnote %}

  For more information, see [this Terraform provider guide](../../terraform/resources/kubernetes_node_group.md).

- API {#api}

  Metadata with credentials for connecting over SSH is provided to the Managed Service for Kubernetes node group as `key=value` pairs.

  {% note warning %}
  
  The `user-data` VM metadata key is not supported for user data transmission. Use the `ssh-keys` key to provide parameters for SSH connections.
  
  {% endnote %}

  To provide multiple credentials for connecting over SSH, convert the contents of the credentials file to a single line and separate the credentials from each other with a sequence of special CRLF characters (`\r\n`). You cannot use multiline messages in an API request with a JSON body.

  Example of converted credentials:

  > ```text
  > testuser1:ssh-ed25519 AAAAB3NzaC***********lP1ww testuser1\r\ntestuser2:ssh-ed25519 ONEMOREkey***********avEHw testuser2
  > ```

  Use the [create](../managed-kubernetes/api-ref/NodeGroup/create.md) REST API method for the [NodeGroup](../managed-kubernetes/api-ref/NodeGroup/index.md) resource or the [NodeGroupService/Create](../managed-kubernetes/api-ref/grpc/NodeGroup/create.md) gRPC API call.

  SSH connection credentials are provided in the `nodeTemplate.metadata` parameter for the REST API or in `node_template.metadata` for the gRPC API using the `ssh-keys` key.

{% endlist %}

For more information about creating a Managed Service for Kubernetes node group and parameters to provide, see [Creating a node group](node-group/node-group-create.md).

## Update node group keys {#node-add-metadata}

To change the credentials for connecting over SSH to a Managed Service for Kubernetes node group, update its metadata.

{% note warning %}

The credentials for connecting over SSH will be completely overwritten. You will not be able to connect to the Managed Service for Kubernetes cluster nodes using the old credentials.

{% endnote %}

{% list tabs group=instructions %}

- Management console {#console}

  {% note warning %}

  After you change the metadata using the [management console](https://console.yandex.cloud), the node group status will temporarily change to `Reconciling`: all the group nodes will be recreated for the changes to take effect.

  {% endnote %}

  1. In the [management console](https://console.yandex.cloud), select a folder.
  1. Navigate to **Managed Service for&nbsp;Kubernetes**.
  1. Select Managed Service for Kubernetes.
  1. In the left-hand panel, select **Node management**.
  1. On the **Node group** tab, select the node group in which you want to update the credentials.
  1. In the top panel, click ![image](../../_assets/console-icons/pencil.svg) **Edit**.
  1. Expand **Metadata**.
  1. Replace the current value of `ssh-keys` with the contents of the credentials file.
  1. Click **Save**.

- CLI {#cli}

  1. View the description of the CLI command for adding and updating the Managed Service for Kubernetes node group metadata:

      ```bash
      yc managed-kubernetes node-group add-metadata --help
      ```

  1. Run this command:

      ```bash
      yc managed-kubernetes node-group add-metadata \
        --name <node_group_name> \
        --metadata-from-file ssh-keys=<path_to_credentials_file>
      ```

      You can get the node group name with the [list of node groups in the folder](node-group/node-group-list.md#list).

- Terraform {#tf}

  1. Open the Terraform configuration file describing the Managed Service for Kubernetes node group.

      For more on how to create such a file, see [Creating a node group](node-group/node-group-create.md).

  1. In the node group description, change the value of the `ssh-keys` metadata key for the `instance_template.metadata` parameter:

      ```hcl
      resource "yandex_kubernetes_node_group" "<node_group_name>" {
        cluster_id = yandex_kubernetes_cluster.<cluster_name>.id
        ...
        instance_template {
          metadata = {
            "ssh-keys" = file("<path_to_credentials_file>")
            ...
          }
          ...
        }
        ...
      }
      ```

  1. Make sure the configuration files are correct.

      1. In the command line, navigate to the directory that contains the current Terraform configuration files defining the infrastructure.
      1. Run this command:
      
         ```bash
         terraform validate
         ```
      
         Terraform will show any errors found in your configuration files.

  1. Confirm resource changes.

      1. Run this command to view the planned changes:
      
         ```bash
         terraform plan
         ```
      
         If you described the configuration correctly, the terminal will display a list of the resources to update and their parameters. This is a verification step that does not apply changes to your resources.
      
      1. If everything looks correct, apply the changes:
         1. Run this command:
      
            ```bash
            terraform apply
            ```
      
         1. Confirm updating the resources.
         1. Wait for the operation to complete.

  For more information, see [this Terraform provider guide](../../terraform/resources/kubernetes_node_group.md).

- API {#api}

  {% note info %}
  
  Below, see parameters for the REST API request body. To specify a parameter in a gRPC API call, convert its name from [lower CamelCase](https://en.wikipedia.org/wiki/Camel_case) to [snake_case](https://en.wikipedia.org/wiki/Snake_case), e.g., `minResourcePresetId` becomes `min_resource_preset_id`.
  
  {% endnote %}

  1. To provide multiple credentials for connecting over SSH, convert the contents of the credentials file to a single line and separate the credentials from each other with a sequence of special CRLF characters (`\r\n`). You cannot use multiline messages in an API request with a JSON body.

      Example of converted credentials:

      > ```text
      > testuser1:ssh-ed25519 AAAAB3NzaC***********lP1ww testuser1\r\ntestuser2:ssh-ed25519 ONEMOREkey***********avEHw testuser2
      > ```

  1. Get all existing metadata for a node group using one of the following methods:
     
     * Use the [get](../managed-kubernetes/api-ref/NodeGroup/get.md) REST API method for the [NodeGroup](../managed-kubernetes/api-ref/NodeGroup/index.md) resource.
     * Use the [NodeGroupService/Get](../managed-kubernetes/api-ref/grpc/NodeGroup/get.md) API call.
     
     In your request, provide the node group ID in the `nodeGroupId` parameter. You can get the ID with the [list of node groups in the folder](node-group/node-group-list.md#list).
     
     The metadata will be listed as `key=value` pairs in the `nodeTemplate.metadata` field of the response.

  1. Use the [update](../managed-kubernetes/api-ref/NodeGroup/update.md) REST API method for the [NodeGroup](../managed-kubernetes/api-ref/NodeGroup/index.md) resource or the [NodeGroupService/Update](../managed-kubernetes/api-ref/grpc/NodeGroup/update.md) gRPC API call, and provide the following in the request:

      * Node group ID in the `nodeGroupId` parameter.

      * `updateMask` parameter set to `nodeTemplate.metadata`.

          {% note warning %}
          
          The API method will assign default values to all the parameters of the object you are modifying unless you explicitly provide them in your request. To avoid this, list the settings you want to change in the `updateMask` parameter as a single comma-separated string.
          
          {% endnote %}

      * `nodeTemplate.metadata` listing all existing node group metadata as `key=value` pairs without any changes.

          For `ssh-keys`, replace the current value with the line with credentials you created.

          {% cut "Example of listing metadata in a parameter" %}

          > * Current metadata keys in a node group:
          >
          >     ```json
          >     "nodeTemplate": {
          >         "metadata": {
          >             "ssh-keys": "<current_credentials_in_single_line>",
          >             "<current_key_1>": "<current_value_1>",
          >             "<current_key_2>": "<current_value_2>"
          >         },
          >         ...
          >     }
          >     ```
          >
          > * Metadata keys to provide in an API request:
          >
          >     ```json
          >     "nodeTemplate": {
          >         "metadata": {
          >             "ssh-keys": "<new_credentials_in_single_line>",
          >             "<current_key_1>": "<current_value_1>",
          >             "<current_key_2>": "<current_value_2>"
          >         }
          >     }
          >     ```

          {% endcut %}

          {% note alert %}
          
          Metadata not listed in `nodeTemplate.metadata` will be deleted.
          
          Then the node group status will temporarily change to **Reconciling**: all the nodes in the group will be recreated for the changes to apply.
          
          {% endnote %}

{% endlist %}

## Get the public IP address of the node {#node-public-ip}

To connect to a Managed Service for Kubernetes cluster node, specify its [public IP address](../../vpc/concepts/address.md#public-addresses). You can find it using one of the following methods.

{% list tabs group=instructions %}

- Management console {#console}

  1. Open the **Compute Cloud** section in the folder hosting your Managed Service for Kubernetes cluster.
  1. In the left-hand panel, select ![image](../../_assets/console-icons/layers-3-diagonal.svg) **Instance groups**.
  1. Click the VM group with the name that matches the Managed Service for Kubernetes node group ID.
  1. In the window that opens, go to the **Virtual machines** tab.
  1. Click the VM whose public address you want to get.
  1. You will find the public IP address under **Network** in **Public IPv4 address**.

- CLI {#cli}

  1. Find out the ID of the VM group that matches the Managed Service for Kubernetes node group.

     The ID is shown in the `INSTANCE GROUP ID` column.

     ```bash
     yc managed-kubernetes node-group list
     ```

     Result:

     ```text
     +----------------------+----------------------+----------------+----------------------+---------------------+---------+------+
     |          ID          |      CLUSTER ID      |      NAME      |  INSTANCE GROUP ID   |     CREATED AT      | STATUS  | SIZE |
     +----------------------+----------------------+----------------+----------------------+---------------------+---------+------+
     | cat684ojo3ir******** | cata9ertn6tc******** | test-nodegroup | cl17i6943n92******** | 2019-04-12 12:38:35 | RUNNING |    2 |
     +----------------------+----------------------+----------------+----------------------+---------------------+---------+------+
     ```

  1. View the list of Managed Service for Kubernetes nodes that belong to this group.

     The public IP address of the Managed Service for Kubernetes node is shown in the `IP` column after `~`.

     ```bash
     yc compute instance-group list-instances cl17i6943n92********
     ```

     Result:

     ```text
     +----------------------+---------------------------+--------------------------+---------------+----------------+
     |     INSTANCE ID      |           NAME            |            IP            |    STATUS     | STATUS MESSAGE |
     +----------------------+---------------------------+--------------------------+---------------+----------------+
     | ef31h24k03pg******** | cl17i6943n92********-itif | 10.0.0.27~84.201.145.251 | RUNNING [53m] |                |
     | ef37ddhg9i7j******** | cl17i6943n92********-ovah | 10.0.0.22~84.201.149.184 | RUNNING [53m] |                |
     +----------------------+---------------------------+--------------------------+---------------+----------------+
     ```

- kubectl CLI {#kubectl}

  1. [Install kubect](https://kubernetes.io/docs/tasks/tools/install-kubectl) and [configure it to work with the new cluster](connect/index.md#kubectl-connect).

  1. Run this command:

     ```bash
     kubectl get nodes -o wide
     ```

     Result:

     ```bash
     NAME                       STATUS  ROLES   AGE  VERSION  INTERNAL-IP  EXTERNAL-IP     OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
     cl17i6943n92********-itif  Ready   <none>  31m  v1.13.3  10.0.0.27    84.201.145.251  Ubuntu 18.04.1 LTS  4.15.0-29-generic  docker://18.6.2
     cl17i6943n92********-ovah  Ready   <none>  31m  v1.13.3  10.0.0.22    84.201.149.184  Ubuntu 18.04.1 LTS  4.15.0-29-generic  docker://18.6.2
     ```

     The public IP address is listed in the `EXTERNAL-IP` column.

{% endlist %}

## Connect to the node {#node-connect}

You can connect to a Managed Service for Kubernetes node over SSH when it is running, i.e., its status is `RUNNING`. To do this, use `ssh` in Linux or macOS, or [PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/) in Windows.

{% list tabs group=operating_system %}

- Linux/macOS/Windows 10 {#linux-macos-windows10}

  In the terminal, run the following command, specifying the username and [public IP address](#node-public-ip) of the node:

  ```bash
  ssh <username>@<node_public_IP_address>
  ```

  If you provided SSH connection credentials when you [created the node group](#node-create) using the management console, use the username you specified in the **Login** field.

  If you provided SSH connection credentials when you [created the node group](#node-create) using the CLI, Terraform, API, or [updated the credentials](#node-add-metadata), use the username you [specified in the SSH connection credentials file](#key-format).

  If this is your first time connecting to a Managed Service for Kubernetes node, you may get the unknown host warning:

  ```bash
  The authenticity of host '130.193.40.101 (130.193.40.101)' can't be established.
  ECDSA key fingerprint is SHA256:PoaSwqxRc8g6iOXtiH7ayGHpSN0MXwUfWHk********.
  Are you sure you want to continue connecting (yes/no)?
  ```

  Type `yes` into the terminal and press **Enter**.

- Windows 7/8 {#windows7-8}

  In Windows, a connection is established using PuTTY.
  1. Run Pageant.
     1. Right-click the Pageant icon in the task bar.
     1. In the context menu, select **Add key**.
     1. Select a PuTTY-generated private key in `.ppk` format. Enter the password for this key, if it is set.
  1. Run PuTTY.
     1. In the **Host Name (or IP address)** field, enter the [public IP address](#node-public-ip) of the VM you want to connect to. Specify port `22` and **SSH** connection type.

        ![ssh_add_ip](../../_assets/compute/ssh-putty/ssh_add_ip.png)

     1. In the tree on the left, select **Connection** - **SSH** - **Auth**.
     1. Enable **Allow agent forwarding**.
     1. In the **Private key file for authentication** field, select the private key file.

        ![ssh_choose_private_key](../../_assets/compute/ssh-putty/ssh_choose_private_key.png)

     1. Go back to the **Sessions** menu. In the **Saved sessions** field, enter any name for the session and click **Save**. This will save the session settings under the specified name. You can use this session profile to connect with Pageant.

        ![ssh_save_session](../../_assets/compute/ssh-putty/ssh_save_session.png)

     1. Click **Open**. If this is your first time connecting to the Managed Service for Kubernetes node, you may get the unknown host warning:

        ![ssh_unknown_host_warning](../../_assets/compute/ssh-putty/ssh_unknown_host_warning.png)

        Click **Yes**. This will open a terminal window prompting you to enter the username to use for connection.

        Enter the username:
        * If you provided SSH connection credentials when you [created the node group](#node-create) using the management console, enter the username you specified in the **Login** field.
        * If you provided SSH connection credentials when you [created the node group](#node-create) using the CLI, Terraform, API, or [updated the credentials](#node-add-metadata), enter the username that you [specified in the SSH connection credentials file](#key-format). 

        Press **Enter**. If everything is configured correctly, a connection to the server will be established.

        ![ssh_login](../../_assets/compute/ssh-putty/ssh_login.png)

  If you saved the session profile in PuTTY, you can use Pageant for future connections:
  1. Right-click the Pageant icon in the task bar.
  1. Select **Saved sessions**.
  1. In the saved sessions list, select the session you need.

{% endlist %}