连接到 Azure Kubernetes 服务 (AKS) 群集节点以进行维护或故障排除

在 Azure Kubernetes 服务 (AKS) 群集的整个生命周期内,最终需要直接访问 AKS 节点。 进行这种访问的原因包括维护、日志收集或故障排除操作。

通过身份验证访问节点,方法因节点 OS 和连接方法而异。 通过本文中讨论的两个选项,安全地针对 AKS Linux 和 Windows 节点进行身份验证。 其中一个选项要求你具有 Kubernetes API 访问权限,另一个是通过 AKS ARM API 完成,该 API 提供直接的专用 IP 信息。 出于安全原因,AKS 节点不会向 Internet 公开。 相反,若要直接连接到任何 AKS 节点,需要使用 kubectl debug 或主机的专用 IP 地址。

使用 Kubernetes API 访问节点

此方法需要使用 kubectl debug 命令。

开始之前

本指南介绍如何创建与 AKS 节点的连接,以及如何更新 AKS 群集的 SSH 密钥。 若要执行这些步骤,需要使用支持 2.0.64 或更高版本的 Azure CLI。 请运行 az --version 检查版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

如果没有 SSH 密钥,请完成下述步骤。 根据节点 OS 映像(适用于 macOS 和 LinuxWindows)创建 SSH 密钥。 务必以 OpenSSH 格式保存密钥对,避免 .ppk 等不受支持的格式。 接下来,请参阅管理 SSH 配置将密钥添加到群集。

Linux 和 macOS

Linux 和 macOS 用户可以使用 kubectl debug 或其专用 IP 地址通过 SSH 访问其节点。 Windows 用户应跳到 Windows Server 代理部分,了解通过代理启用 SSH 的解决方法。

使用 kubectl 调试的 SSH

若要创建交互式 shell 连接,请使用 kubectl debug 命令在节点上运行特权容器。

  1. 若要列出节点,请使用 kubectl get nodes 命令:

    kubectl get nodes -o wide
    

    示例输出:

    NAME                                STATUS   ROLES   AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE
    aks-nodepool1-37663765-vmss000000   Ready    agent   166m   v1.25.6   10.224.0.33   <none>        Ubuntu 22.04.2 LTS
    aks-nodepool1-37663765-vmss000001   Ready    agent   166m   v1.25.6   10.224.0.4    <none>        Ubuntu 22.04.2 LTS
    aksnpwin000000                      Ready    agent   160m   v1.25.6   10.224.0.62   <none>        Windows Server 2022 Datacenter
    
  2. 使用 kubectl debug 命令在节点上启动特权容器,然后连接到该容器。

    kubectl debug node/aks-nodepool1-37663765-vmss000000 -it --image=mcr.azk8s.cn/cbl-mariner/busybox:2.0
    

    示例输出:

    Creating debugging pod node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx with container debugger on node aks-nodepool1-37663765-vmss000000.
    If you don't see a command prompt, try pressing enter.
    root@aks-nodepool1-37663765-vmss000000:/#
    

    现在,可以通过特权容器作为调试 Pod 访问节点。

    注意

    可以通过从特权容器运行 chroot /host 与节点会话进行交互。

退出 kubectl 调试模式

完成 Pod 操作后,输入 exit 命令以结束交互式 shell 会话。 交互式容器会话关闭后,请删除与 kubectl delete pod 一起使用的调试 Pod。

kubectl delete pod node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx

SSH 的 Windows Server 代理连接

请遵循以下步骤,在 Windows Server 节点上使用 SSH 进行连接。

创建代理服务器

目前,无法通过使用 kubectl debug 直接连接到 Windows Server 节点。 相反,需要先使用 kubectl 连接到群集中的另一个节点,然后使用 SSH 从该节点连接到 Windows Server 节点。

若要连接到群集中的另一个节点,请使用 kubectl debug 命令。 有关详细信息,请按照 kubectl 部分中的上述步骤操作。 使用创建 AKS 群集时提供的 SSH 密钥和 Windows Server 节点的内部 IP 地址,从另一个节点创建与 Windows Server 节点的 SSH 连接。

重要

只有在结合使用 Azure CLI 和 --generate-ssh-keys 参数创建了 AKS 群集时,才能按照以下步骤从另一个节点创建与 Windows Server 节点的 SSH 连接。 如果想要改用自己的 SSH 密钥,可以使用 az aks update 来管理现有 AKS 群集上的 SSH 密钥。 有关详细信息,请参阅管理 SSH 节点访问

注意

如果 Linux 代理节点关闭或无响应,请转而使用 Azure Bastion 方法进行连接。

  1. 使用 kubectl debug 命令在代理 (Linux) 节点上启动特权容器,然后连接到该容器。

    kubectl debug node/aks-nodepool1-37663765-vmss000000 -it --image=mcr.azk8s.cn/cbl-mariner/busybox:2.0
    

    示例输出:

    Creating debugging pod node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx with container debugger on node aks-nodepool1-37663765-vmss000000.
    If you don't see a command prompt, try pressing enter.
    root@aks-nodepool1-37663765-vmss000000:/#
    
  2. 打开新的终端窗口,并使用 kubectl get pods 命令获取 kubectl debug 启动的 Pod 的名称。

    kubectl get pods
    

    示例输出:

    NAME                                                    READY   STATUS    RESTARTS   AGE
    node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx   1/1     Running   0          21s
    

    在示例输出中,node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx 是由 kubectl debug 启动的 Pod 的名称

  3. 使用 kubectl port-forward 命令打开到已部署的 Pod 的连接:

    kubectl port-forward node-debugger-aks-nodepool1-37663765-vmss000000-bkmmx 2022:22
    

    示例输出:

    Forwarding from 127.0.0.1:2022 -> 22
    Forwarding from [::1]:2022 -> 22
    

    上面的示例从开发计算机上的端口 2022 开始将网络流量转发到部署的 pod 上的端口 22。 使用 kubectl port-forward 打开连接并转发网络流量时,在停止 kubectl port-forward 命令之前,连接将一直保持打开状态。

  4. 打开新终端并运行 kubectl get nodes 命令,以显示 Windows Server 节点的内部 IP 地址:

    kubectl get no -o custom-columns=NAME:metadata.name,'INTERNAL_IP:status.addresses[?(@.type == \"InternalIP\")].address'
    

    示例输出:

    NAME                                INTERNAL_IP
    aks-nodepool1-19409214-vmss000003   10.224.0.8
    

    在上例中,10.224.0.62 是 Windows Server 节点的内部 IP 地址。

  5. 使用内部 IP 地址创建到 Windows Server 节点的 SSH 连接,并通过开发计算机上的端口 2022 连接到端口 22。 AKS 节点的默认用户名为 azureuser。 接受提示以继续进行连接。 然后,系统会提供 Windows Server 节点的 bash 提示:

    ssh -o 'ProxyCommand ssh -p 2022 -W %h:%p azureuser@127.0.0.1' azureuser@10.224.0.62
    

    示例输出:

    The authenticity of host '10.224.0.62 (10.224.0.62)' can't be established.
    ECDSA key fingerprint is SHA256:1234567890abcdefghijklmnopqrstuvwxyzABCDEFG.
    Are you sure you want to continue connecting (yes/no)? yes
    

    注意

    如果希望使用密码验证,请包含参数 -o PreferredAuthentications=password。 例如:

     ssh -o 'ProxyCommand ssh -p 2022 -W %h:%p azureuser@127.0.0.1' -o PreferredAuthentications=password azureuser@10.224.0.62
    

使用主机进程容器访问 Windows 节点

  1. 使用以下内容创建 hostprocess.yaml,并将 AKSWINDOWSNODENAME 替换为 AKS Windows 节点名称。

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        pod: hpc
      name: hpc
    spec:
      securityContext:
        windowsOptions:
          hostProcess: true
          runAsUserName: "NT AUTHORITY\\SYSTEM"
      hostNetwork: true
      containers:
        - name: hpc
          image: mcr.azk8s.cn/windows/servercore:ltsc2022 # Use servercore:1809 for WS2019
          command:
            - powershell.exe
            - -Command
            - "Start-Sleep 2147483"
          imagePullPolicy: IfNotPresent
      nodeSelector:
        kubernetes.io/os: windows
        kubernetes.io/hostname: AKSWINDOWSNODENAME
      tolerations:
        - effect: NoSchedule
          key: node.kubernetes.io/unschedulable
          operator: Exists
        - effect: NoSchedule
          key: node.kubernetes.io/network-unavailable
          operator: Exists
        - effect: NoExecute
          key: node.kubernetes.io/unreachable
          operator: Exists
    
  2. 运行 kubectl apply -f hostprocess.yaml 以在指定的 Windows 节点中部署 Windows 主机进程容器 (HPC)。

  3. 使用 kubectl exec -it [HPC-POD-NAME] -- powershell

  4. 可以在 HPC 容器内运行任何 PowerShell 命令来访问 Windows 节点。

注意

需要将根文件夹切换到 HPC 容器内的 C:\ 才能访问 Windows 节点中的文件。

使用 Azure Bastion for Windows 的 SSH

如果无法访问 Linux 代理节点,替代方法是使用 Azure Bastion 作为代理。 此方法要求你为群集所在的虚拟网络设置 Azure Bastion 主机。 有关更多详细信息,请参阅使用 Azure Bastion 进行连接

从 AKS API 使用专用 IP 进行 SSH 连接(预览)

如果无权访问 Kubernetes API,可通过 AKS 代理池 API(预览版)(在预览版 07-02-2023 或更高版本上可用)获取访问 Node IPNode Name 等属性的权限,以连接到 AKS 节点。

重要

AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

使用 IP 地址创建与节点的交互式 shell 连接

为方便起见,AKS 节点通过专用 IP 地址在群集的虚拟网络上公开。 但是,需要在群集的虚拟网络中通过 SSH 连接到节点。 如果尚未配置环境,可使用 Azure Bastion 建立一个代理,可以从该代理通过 SSH 连接到群集节点。 确保 Azure Bastion 部署在群集所在的同一虚拟网络中。

  1. 使用 az aks machine list 命令获取专用 IP,面向具有 --nodepool-name 标志的特定节点池中的所有 VM。

    az aks machine list --resource-group myResourceGroup  --cluster-name myAKSCluster --nodepool-name nodepool1 -o table
    

    以下示例输出显示了节点池中所有节点的内部 IP 地址:

    Name                               Ip           Family
    ---------------------------------  -----------  -----------
    aks-nodepool1-33555069-vmss000000  10.224.0.5   IPv4
    aks-nodepool1-33555069-vmss000001  10.224.0.6   IPv4
    aks-nodepool1-33555069-vmss000002  10.224.0.4   IPv4
    

    若要以节点池中的特定节点为目标,请使用 --machine-name 标志:

    az aks machine show --cluster-name myAKScluster --nodepool-name nodepool1 -g myResourceGroup --machine-name aks-nodepool1-33555069-vmss000000 -o table
    

    以下示例输出显示了所有指定节点的内部 IP 地址:

    Name                               Ip         Family
    ---------------------------------  -----------  -----------
    aks-nodepool1-33555069-vmss000000  10.224.0.5   IPv4
    
  2. 使用在上一步中获取的专用 IP 地址通过 SSH 连接到节点。 此步骤仅适用于 Linux 计算机。 对于 Windows 计算机,请参阅使用 Azure Bastion 进行连接

    ssh -i /path/to/private_key.pem azureuser@10.224.0.33
    

后续步骤

如需更多故障排除数据,可查看 kubelet 日志查看 Kubernetes 控制平面日志

若要了解如何管理 SSH 密钥,请参阅管理 SSH 配置