IBM Cloud Docs
为什么我无法通过 SSH 登录到工作程序节点?

为什么我无法通过 SSH 登录到工作程序节点?

虚拟私有云 经典基础架构

您无法通过 SSH 连接访问工作站节点。

通过密码进行 SSH 在工作程序节点上不可用。

要在每个工作程序节点上运行操作,请使用 Kubernetes DaemonSet,或者将作业用于一次性操作。

要获取主机对工作程序节点的访问权以进行调试和故障诊断,请查看以下选项。

使用 oc debug 进行调试

使用 oc debug node 命令将具有特权 securityContext 的 pod 部署到要进行故障诊断的工作程序节点。

调试 pod 与交互式 shell 一起部署,以便您可以在创建 pod 后立即访问工作程序节点。 有关 oc debug node 命令的工作方式的更多信息,请参阅 此 Red Hat 博客帖子

  1. 获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。

    oc get nodes -o wide
    
  2. 创建具有主机访问权的调试 pod。 创建 pod 时,会自动打开 pod 的交互式 shell。 如果 oc debug node 命令失败,请继续选项 2。

    oc debug node/<NODE_NAME>
    

    如果 oc debug node/<NODE_NAME> 命令失败,那么可能存在阻止拉取缺省容器映像的安全组,ACL 或防火墙规则。 使用 --image=us.icr.io/armada-master/network-alpine:latest 选项再次尝试执行命令,该选项使用可通过专用网络访问的 IBM Cloud Container Registry中的映像。

  3. 运行调试命令以帮助您收集信息并对问题进行故障诊断。 可用于调试的命令 (例如 tcpdumpcurlipifconfigncpingps) 已在 shell 中可用。 您还可以通过运行 yum install <tool> 来安装其他工具,例如 mtrconntrack

使用 kubectl exec 进行调试

如果无法使用 oc debug node 命令,那么可以创建具有特权 securityContext 的 Alpine pod,并使用 kubectl exec 命令从 pod 的交互式 shell 运行调试命令。

  1. 获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。

    oc get nodes -o wide
    
  2. 导出环境变量中的名称。

    export NODE=<NODE_NAME>
    
  3. 在工作程序节点上创建调试 pod。 此处的 Docker 高山映像用作示例。 如果工作程序节点没有公用网络访问权,那么您可以维护映像副本以在自己的 ICR 存储库中进行调试,或者使用其他工具构建定制映像以满足您的需求。

    kubectl apply -f - << EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: debug-${NODE}
      namespace: default
    spec:
      tolerations:
      - operator: "Exists"
      hostNetwork: true
      containers:
      - args: ["-c", "sleep 20d"]
        command: ["/bin/sh"]
        image: us.icr.io/armada-master/network-alpine:latest
        imagePullPolicy: Always
        name: debug
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /host
          name: host-volume
      volumes:
      - name: host-volume
        hostPath:
          path: /
      nodeSelector:
        kubernetes.io/hostname: ${NODE}
      restartPolicy: Never
    EOF
    
  4. 登录调试 pod。 将自动打开 pod 的交互式 shell。 如果 kubectl exec 命令失败,请继续选项 3。

    kubectl exec -it debug-${NODE} -- sh
    

    要从工作程序节点获取日志或其他文件,请使用以下格式的 **kubectl cp** 命令。 以下示例从工作程序节点的主机文件系统获取 /var/log/messages 文件。

    oc cp default/debug-${NODE}:/host/var/log/messages ./messages
    

    获取以下日志以查找工作程序节点上的问题。

    /var/log/messages
    /var/log/kubelet.log
    /var/log/crio.log
    /var/log/calico/cni/cni.log
    
  5. 运行调试命令以帮助您收集信息并对问题进行故障诊断。 可用于调试的命令 (例如 digtcpdumpmtrcurlipifconfigncpingps) 在 shell 中已可用。 您还可以通过运行 apk add <tool> 来安装其他工具,例如 conntrack。 例如,要添加 conntrack,请运行 apk add conntrack-tools

  6. 删除您为调试而创建的主机访问 pod。

    kubectl delete pod debug-${NODE}
    

通过在工作程序节点上启用 root 用户 SSH 访问进行调试

如果无法使用 oc debug nodekubectl exec 命令 (例如,如果集群主节点与工作程序节点之间的 VPN 连接已关闭),那么可以创建支持 root 用户 SSH 访问的 pod,并将公用 SSH 密钥复制到工作程序节点以进行 SSH 访问。

允许 root 用户 SSH 访问是一个安全风险。 仅当需要 SSH 访问并且没有其他选项可用于对工作程序节点问题进行故障诊断时,才允许进行 SSH 访问。 完成故障诊断时,请确保遵循 调试后清除 部分中的步骤来禁用 SSH 访问。

  1. 选择现有公用 SSH 密钥或创建新的公用 SSH 密钥。

    ssh-keygen -f /tmp/id_rsa_cluster_worker -t rsa -b 4096 -C temp-worker-ssh-key -P ''
    ls /tmp
    
    id_rsa_cluster_worker id_rsa_cluster_worker.pub
    
    cat /tmp/id_rsa_cluster_worker.pub
    
  2. 获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。

    oc get nodes -o wide
    
  3. 为调试 pod 创建以下 YAML 文件,并将该文件另存为 enable-ssh.yaml。 将 <NODE_NAME> 替换为工作程序节点名,并将 SSH_PUBLIC_KEY 的示例 value 替换为公用 SSH 密钥。 此处的 Docker 高山映像用作示例。 如果工作程序节点没有公用网络访问权,那么您可以保留映像的副本以在自己的 ICR 存储库中进行调试,或者使用其他工具构建定制映像以满足您的需求。

    apiVersion: v1
    kind: Pod
    metadata:
      name: enable-ssh-<NODE_NAME>
      labels:
        name: enable-ssh
    spec:
      tolerations:
      - operator: "Exists"
      hostNetwork: true
      hostPID: true
      hostIPC: true
      containers:
      - image: us.icr.io/armada-master/network-alpine:latest
        env:
        - name: SSH_PUBLIC_KEY
          value: "<ssh-rsa AAA...ZZZ temp-worker-ssh-key>"
        args: ["-c", "echo $(SSH_PUBLIC_KEY) | tee -a /root/.ssh/authorized_keys && sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/g' /host/etc/ssh/sshd_config && sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/g' /host/etc/ssh/sshd_config.d/40-rhcos-defaults.conf || true && killall -1 sshd || yes n | ssh-keygen -f /host/etc/ssh/ssh_host_rsa_key -t rsa -b 4096 -C temp-server-ssh-key -P '' && while true; do sleep 86400; done"]
        command: ["/bin/sh"]
        name: enable-ssh
        securityContext:
          privileged: true
        volumeMounts:
        - mountPath: /host
          name: host-volume
        - mountPath: /root/.ssh
          name: ssh-volume
      volumes:
      - name: host-volume
        hostPath:
          path: /
      - name: ssh-volume
        hostPath:
          path: /root/.ssh
      nodeSelector:
        kubernetes.io/hostname: <NODE_NAME>
      restartPolicy: Never
    
  4. 在群集中创建 pod。 创建此 pod 时,会将公用密钥添加到工作程序节点,并将 SSH 配置为允许 root 用户 SSH 登录。

    oc apply -f enable-ssh.yaml
    
  5. 使用专用或公用网络通过 SSH 密钥访问工作程序节点。

通过 SSH 登录到专用网络上的工作程序

创建新的或选择有权访问与工作程序节点相同的专用网络的现有服务器实例。 对于 VPC 集群,虚拟服务器实例 必须与工作程序节点存在于同一 VPC 中。

对于经典集群,如果启用了 虚拟路由器功能(VRF)VLAN 生成,那么 设备 可以从任何专用 VLAN 访问工作程序节点。 否则,设备必须存在于与工作程序节点相同的专用 VLAN 上。

  1. 将步骤 1 中的 SSH 专用密钥从本地计算机复制到此服务器实例。

    scp <SSH_private_key_location> <user@host>:/.ssh/id_rsa_worker_private
    
  2. 通过 SSH 登录到服务器实例。

  3. 设置正确的许可权以使用您复制的 SSH 专用密钥。

    chmod 400 ~/.ssh/id_rsa_worker_private
    
  4. 使用专用密钥以 SSH 方式连接到在步骤 2 中找到的工作程序节点。

    ssh -i ~/.ssh/id_rsa_worker_private root@<WORKER_PRIVATE_IP>
    

通过 SSH 登录到公用网络上的工作程序节点

通过登录到工作程序节点来调试连接到公用 VLAN 的经典集群。

  1. 安装和配置 Calico CLI,并设置集群的上下文以运行 Calico 命令

  2. 创建名为 ssh-open 的 Calico 全局网络策略,以允许端口 22 上的入站 SSH 流量。

    calicoctl apply -f - <<EOF
    apiVersion: projectcalico.org/v3
    kind: GlobalNetworkPolicy
    metadata:
      name: ssh-open
    spec:
      selector: ibm.role == 'worker_public'
      ingress:
      - action: Allow
        protocol: TCP
        destination:
          ports:
          - 22
      order: 1500
    EOF
    
  3. 获取工作节点的公共 IP 地址。

    oc get nodes -o wide
    
  4. 通过其公共 IP 地址通过 SSH 登录到工作程序节点。

    ssh -i <SSH_private_key_location> root@<WORKER_PUBLIC_IP>
    
  5. 运行调试命令以帮助您收集信息并对问题进行故障诊断,例如 ipifconfigpingpscurl。 您还可以通过运行 yum install <tool> 来安装缺省情况下可能未安装的其他工具,例如 tcpdumpnc

调试后清除

完成调试后,清除资源以禁用 SSH 访问。

  1. 删除 SSH 启用 pod。

    oc delete pod enable-ssh-<NODE_NAME>
    
  2. 如果通过公用网络访问了工作程序节点,请删除 Calico 策略,以便再次阻止端口 22。

    calicoctl delete gnp ssh-open [-c <path_to_calicoctl_cfg>/calicoctl.cfg]
    
  3. 重新装入经典工作程序节点替换 VPC 工作程序节点,以便使用原始 SSH 配置并除去添加的 SSH 密钥。