sigs.k8s.io/cluster-api-provider-azure@v1.14.3/docs/book/src/topics/ssh-access.md (about) 1 # SSH access to nodes 2 3 This document describes how to get SSH access to virtual machines that are part of a CAPZ cluster. 4 5 In order to get SSH access to a Virtual Machine on Azure, two requirements have to be met: 6 7 - get network-level access to the SSH service 8 - get authentication sorted 9 10 This documents describe some possible strategies to fulfill both requirements. 11 12 ## Network Access 13 14 ### Default behavior 15 16 By default, `control plane` VMs have SSH access allowed from any source in their `Network Security Group`s. Also by default, 17 VMs don't have a public IP address assigned. 18 19 To get SSH access to one of the `control plane` VMs you can use the `API Load Balancer`'s IP, because by default an `Inbound NAT Rule` 20 is created to route traffic coming to the load balancer on TCP port 22 (the SSH port) to one of the nodes with role `master` in the workload cluster. 21 22 This of course works only for clusters that are using a `Public` Load Balancer. 23 24 In order to reach all other VMs, you can use the NATted control plane VM as a bastion host and use the private IP 25 address for the other nodes. 26 27 For example, let's consider this CAPZ cluster (using a Public Load Balancer) with two nodes: 28 29 ```shell 30 NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME 31 test1-control-plane-cn9lm Ready control-plane,master 111m v1.18.16 10.0.0.4 <none> Ubuntu 18.04.5 LTS 5.4.0-1039-azure containerd://1.4.3 32 test1-md-0-scctm Ready <none> 109m v1.18.16 10.1.0.4 <none> Ubuntu 18.04.5 LTS 5.4.0-1039-azure containerd://1.4.3 33 ``` 34 35 You can SSH to the control plane node using the load balancer's public DNS name: 36 37 ```shell 38 $ kubectl get azurecluster test1 -o json | jq '.spec.networkSpec.apiServerLB.frontendIPs[0].publicIP.dnsName' 39 test1-21192f78.eastus.cloudapp.azure.com 40 41 $ ssh username@test1-21192f78.eastus.cloudapp.azure.com hostname 42 test1-control-plane-cn9lm 43 ``` 44 45 As you can see, the Load Balancer routed the request to node `test1-control-plane-cn9lm` that is the only node with role `control-plane` in this workload cluster. 46 47 In order to SSH to node 'test1-md-0-scctm', you can use the other node as a bastion: 48 49 ```shell 50 $ ssh -J username@test1-21192f78.eastus.cloudapp.azure.com username@10.1.0.4 hostname 51 test1-md-0-scctm 52 ``` 53 54 Clusters using an `Internal` Load Balancer (private clusters) can't use this approach. Network-level SSH access to those clusters has to be made on the private IP address of VMs 55 by first getting access to the Virtual Network. How to do that is out of the scope of this document. 56 A possible alternative that works for private clusters as well is described in the next paragraph. 57 58 ### Azure Bastion 59 60 A possible alternative to the process described above is to use the [`Azure Bastion`](https://learn.microsoft.com/azure/bastion/bastion-overview) feature. 61 This approach works the same way for workload clusters using either type of `Load Balancers`. 62 63 In order to enable `Azure Bastion` on a CAPZ workload cluster, edit the `AzureCluster` CR and set the `spec/bastionSpec/azureBastion` field. 64 It is enough to set the field's value to the empty object `{}` and the default configuration settings will be used while deploying the `Azure Bastion`. 65 66 For example this is an `AzureCluster` CR with the `Azure Bastion` feature enabled: 67 68 ```yaml 69 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 70 kind: AzureCluster 71 metadata: 72 name: test1 73 namespace: default 74 spec: 75 bastionSpec: 76 azureBastion: {} 77 ... 78 ``` 79 80 Once the `Azure Bastion` is deployed, it will be possible to SSH to any of the cluster VMs through the 81 `Azure Portal`. Please follow the [official documentation](https://learn.microsoft.com/azure/bastion/bastion-overview) 82 for a deeper explanation on how to do that. 83 84 #### Advanced settings 85 86 When the `AzureBastion` feature is enabled in a CAPZ cluster, 3 new resources will be deployed in the resource group: 87 88 - The `Azure Bastion` resource; 89 - A subnet named `AzureBastionSubnet` (the name is mandatory and can't be changed); 90 - A public `IP address`. 91 92 The default values for the new resources should work for most use cases, but if you need to customize them you can 93 provide your own values. Here is a detailed example: 94 95 ```yaml 96 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 97 kind: AzureCluster 98 metadata: 99 name: test1 100 namespace: default 101 spec: 102 bastionSpec: 103 azureBastion: 104 name: "..." // The name of the Azure Bastion, defaults to '<cluster name>-azure-bastion' 105 subnet: 106 name: "..." // The name of the Subnet. The only supported name is `AzureBastionSubnet` (this is an Azure limitation). 107 securityGroup: {} // No security group is assigned by default. You can choose to have one created and assigned by defining it. 108 publicIP: 109 "name": "..." // The name of the Public IP, defaults to '<cluster name>-azure-bastion-pip'. 110 sku: "..." // The SKU/tier of the Azure Bastion resource. The options are `Standard` and `Basic`. The default value is `Basic`. 111 enableTunneling: "..." // Whether or not to enable tunneling/native client support. The default value is `false`. 112 ``` 113 114 If you specify a security group to be associated with the Azure Bastion subnet, it needs to have some networking rules defined or 115 the `Azure Bastion` resource creation will fail. Please refer to [the documentation](https://learn.microsoft.com/azure/bastion/bastion-nsg) for more details. 116 117 ## Authentication 118 119 With the networking part sorted, we still have to work out a way of authenticating to the VMs via SSH. 120 121 ### Provisioning SSH keys using Machine Templates 122 123 In order to add an SSH authorized key for user `username` and provide `sudo` access to the `control plane` VMs, you can adjust the `KubeadmControlPlane` CR 124 as in the following example: 125 126 ```yaml 127 apiVersion: controlplane.cluster.x-k8s.io/v1beta1 128 kind: KubeadmControlPlane 129 ... 130 spec: 131 ... 132 kubeadmConfigSpec: 133 ... 134 users: 135 - name: username 136 sshAuthorizedKeys: 137 - "ssh-rsa AAAA..." 138 files: 139 - content: "username ALL = (ALL) NOPASSWD: ALL" 140 owner: root:root 141 path: /etc/sudoers.d/username 142 permissions: "0440" 143 ... 144 ``` 145 146 Similarly, you can achieve the same result for `Machine Deployments` by customizing the `KubeadmConfigTemplate` CR: 147 148 ```yaml 149 apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 150 kind: KubeadmConfigTemplate 151 metadata: 152 name: test1-md-0 153 namespace: default 154 spec: 155 template: 156 spec: 157 files: 158 ... 159 - content: "username ALL = (ALL) NOPASSWD: ALL" 160 owner: root:root 161 path: /etc/sudoers.d/username 162 permissions: "0440" 163 ... 164 users: 165 - name: username 166 sshAuthorizedKeys: 167 - "ssh-rsa AAAA..." 168 ``` 169 170 ### Setting SSH keys or passwords using the Azure Portal 171 172 An alternative way of gaining SSH access to VMs on Azure is to set the `password` or `authorized key` via the `Azure Portal`. 173 In the Portal, navigate to the `Virtual Machine` details page and find the `Reset password` function in the left pane.