为什么我无法通过 SSH 登录到工作程序节点?
虚拟私有云 经典基础架构
您无法通过 SSH 连接访问工作站节点。
通过密码进行 SSH 在工作程序节点上不可用。
要在每个工作程序节点上运行操作,请使用 Kubernetes DaemonSet
,或者将作业用于一次性操作。
要获取主机对工作程序节点的访问权以进行调试和故障诊断,请查看以下选项。
使用 oc debug
进行调试
使用 oc debug node
命令将具有特权 securityContext
的 pod 部署到要进行故障诊断的工作程序节点。
调试 pod 与交互式 shell 一起部署,以便您可以在创建 pod 后立即访问工作程序节点。 有关 oc debug node
命令的工作方式的更多信息,请参阅 此 Red Hat 博客帖子。
-
获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。
oc get nodes -o wide
-
创建具有主机访问权的调试 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中的映像。 -
运行调试命令以帮助您收集信息并对问题进行故障诊断。 可用于调试的命令 (例如
tcpdump
,curl
,ip
,ifconfig
,nc
,ping
和ps
) 已在 shell 中可用。 您还可以通过运行yum install <tool>
来安装其他工具,例如mtr
和conntrack
。
使用 kubectl exec
进行调试
如果无法使用 oc debug node
命令,那么可以创建具有特权 securityContext
的 Alpine pod,并使用 kubectl exec
命令从 pod 的交互式 shell 运行调试命令。
-
获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。
oc get nodes -o wide
-
导出环境变量中的名称。
export NODE=<NODE_NAME>
-
在工作程序节点上创建调试 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
-
登录调试 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
-
运行调试命令以帮助您收集信息并对问题进行故障诊断。 可用于调试的命令 (例如
dig
,tcpdump
,mtr
,curl
,ip
,ifconfig
,nc
,ping
和ps
) 在 shell 中已可用。 您还可以通过运行apk add <tool>
来安装其他工具,例如conntrack
。 例如,要添加conntrack
,请运行apk add conntrack-tools
。 -
删除您为调试而创建的主机访问 pod。
kubectl delete pod debug-${NODE}
通过在工作程序节点上启用 root 用户 SSH 访问进行调试
如果无法使用 oc debug node
或 kubectl exec
命令 (例如,如果集群主节点与工作程序节点之间的 VPN 连接已关闭),那么可以创建支持 root 用户 SSH 访问的 pod,并将公用 SSH 密钥复制到工作程序节点以进行 SSH 访问。
允许 root 用户 SSH 访问是一个安全风险。 仅当需要 SSH 访问并且没有其他选项可用于对工作程序节点问题进行故障诊断时,才允许进行 SSH 访问。 完成故障诊断时,请确保遵循 调试后清除 部分中的步骤来禁用 SSH 访问。
-
选择现有公用 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
-
获取要访问的 Worker 节点的名称。 对于 CoreOS 工作程序节点,名称是工作程序的主机名。 对于所有其他工作程序节点,工作程序节点名称是专用 IP 地址。
oc get nodes -o wide
-
为调试 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
-
在群集中创建 pod。 创建此 pod 时,会将公用密钥添加到工作程序节点,并将 SSH 配置为允许 root 用户 SSH 登录。
oc apply -f enable-ssh.yaml
-
使用专用或公用网络通过 SSH 密钥访问工作程序节点。
通过 SSH 登录到专用网络上的工作程序
创建新的或选择有权访问与工作程序节点相同的专用网络的现有服务器实例。 对于 VPC 集群,虚拟服务器实例 必须与工作程序节点存在于同一 VPC 中。
对于经典集群,如果启用了 虚拟路由器功能(VRF) 或 VLAN 生成,那么 设备 可以从任何专用 VLAN 访问工作程序节点。 否则,设备必须存在于与工作程序节点相同的专用 VLAN 上。
-
将步骤 1 中的 SSH 专用密钥从本地计算机复制到此服务器实例。
scp <SSH_private_key_location> <user@host>:/.ssh/id_rsa_worker_private
-
通过 SSH 登录到服务器实例。
-
设置正确的许可权以使用您复制的 SSH 专用密钥。
chmod 400 ~/.ssh/id_rsa_worker_private
-
使用专用密钥以 SSH 方式连接到在步骤 2 中找到的工作程序节点。
ssh -i ~/.ssh/id_rsa_worker_private root@<WORKER_PRIVATE_IP>
通过 SSH 登录到公用网络上的工作程序节点
通过登录到工作程序节点来调试连接到公用 VLAN 的经典集群。
-
创建名为
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
-
获取工作节点的公共 IP 地址。
oc get nodes -o wide
-
通过其公共 IP 地址通过 SSH 登录到工作程序节点。
ssh -i <SSH_private_key_location> root@<WORKER_PUBLIC_IP>
-
运行调试命令以帮助您收集信息并对问题进行故障诊断,例如
ip
,ifconfig
,ping
,ps
和curl
。 您还可以通过运行yum install <tool>
来安装缺省情况下可能未安装的其他工具,例如tcpdump
或nc
。
调试后清除
完成调试后,清除资源以禁用 SSH 访问。
-
删除 SSH 启用 pod。
oc delete pod enable-ssh-<NODE_NAME>
-
如果通过公用网络访问了工作程序节点,请删除 Calico 策略,以便再次阻止端口 22。
calicoctl delete gnp ssh-open [-c <path_to_calicoctl_cfg>/calicoctl.cfg]
-
重新装入经典工作程序节点 或 替换 VPC 工作程序节点,以便使用原始 SSH 配置并除去添加的 SSH 密钥。