IBM Cloud Docs
ワーカー・ノードに SSH できないのはなぜですか?

ワーカー・ノードに SSH できないのはなぜですか?

仮想プライベート・クラウド クラシック・インフラストラクチャー

SSH 接続を使用してワーカー・ノードにアクセスすることはできません。

パスワードによる SSH は、ワーカー・ノードでは使用できません。

すべてのワーカーノードでアクションを実行するには、Kubernetes DaemonSet を使うか、1回限りのアクションにはジョブを使う。

デバッグおよびトラブルシューティングの目的でワーカー・ノードへのホスト・アクセスを取得するには、以下のオプションを確認します。

kubectl debug を使用したデバッグ

kubectl debug node コマンドを使用して、特権 securityContext を持つポッドを、トラブルシューティングするワーカー・ノードにデプロイします。

このデバッグ・ポッドは対話式シェルとともにデプロイされるので、ポッドが作成されたらすぐにワーカー・ノードにアクセスできます。 kubectl debug node コマンドの動作について詳しくは、 「 Kubernetes リファレンス」の「 debug コマンド」を参照してください。

  1. アクセスするワーカー・ノードの名前を確認します。 CoreOS ワーカー・ノードの場合、名前はワーカーのホスト名です。 他のすべてのワーカー・ノードの場合、ワーカー・ノード名はプライベート IP アドレスです。
    kubectl get nodes -o wide
    
  2. ホスト・アクセスが可能なデバッグ・ポッドを作成します。 ポッドが作成されたら、ポッドの対話式シェルが自動的に開かれます。 kubectl debug node コマンドが失敗した場合は、オプション 2 に進みます。
    kubectl debug --image=us.icr.io/armada-master/network-alpine:latest -it node/<NODE_NAME> -- sh
    
  3. 情報を収集して問題をトラブルシューティングするのに役立つデバッグ・コマンドを実行します。 tcpdumpcurlipifconfigncpingps など、デバッグで一般的に使用されるコマンドが既にシェルに用意されています。 mtrconntrack のような他のツールも、apk add <tool> を実行することでインストールできます。

kubectl exec を使用したデバッグ

kubectl debug node コマンドを使用できない場合は、特権 securityContext を持つ Alpine ポッドを作成し、kubectl exec コマンドを使用して、ポッドの対話式シェルからデバッグ・コマンドを実行できます。

  1. アクセスするワーカー・ノードの名前を確認します。 CoreOS ワーカー・ノードの場合、名前はワーカーのホスト名です。 他のすべてのワーカー・ノードの場合、ワーカー・ノード名はプライベート IP アドレスです。

    kubectl get nodes -o wide
    
  2. 名前を環境変数にエクスポートします。

    export NODE=<NODE_NAME>
    
  3. ワーカー・ノード上にデバッグ・ポッドを作成します。 ここでは、Docker alpine のイメージを例として使用しています。 ワーカーノードがパブリックなネットワークアクセスを持っていない場合、デバッグ用のイメージのコピーを自分の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. デバッグ・ポッドにログインします。 ポッドの対話式シェルが自動的に開かれます。 kubectl exec コマンドが失敗した場合は、オプション 3 に進みます。

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

    kubectl cp コマンドを使って、ワーカーノードからログやその他のファイルを取得することができる。 次の例は、/var/log/syslog ファイルを取得します。

    kubectl cp --retries 20 default/debug-${NODE}:/host/var/log/syslog ./syslog
    

    以下のログを取得して、ワーカー・ノード上の問題を探します。

    /var/log/syslog
    /var/log/containerd.log
    /var/log/kubelet.log
    /var/log/kern.log
    
  5. 情報を収集して問題をトラブルシューティングするのに役立つデバッグ・コマンドを実行します。 digtcpdumpmtrcurlipifconfigncpingps など、デバッグに使うようなコマンドは、すでにシェルで使えるようになっている。 apk add <tool> を実行すれば、conntrack のような他のツールもインストールできます。 例えば、conntrack を追加するには、apk add conntrack-tools を実行します。

  6. デバッグ用に作成したホスト・アクセス・ポッドを削除します。

    kubectl delete pod debug-${NODE}
    

ワーカー・ノードで root SSH アクセスを有効にしてデバッグする

クラスター・マスターとワーカー・ノードの間の VPN 接続がダウンしているなど、kubectl debug node コマンドまたは kubectl exec コマンドを使用できない場合は、root SSH アクセスを有効にし、SSH アクセスのために公開 SSH 鍵をワーカー・ノードにコピーするポッドを作成できます。

root 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. アクセスするワーカー・ノードの名前を確認します。 CoreOS ワーカー・ノードの場合、名前はワーカーのホスト名です。 他のすべてのワーカー・ノードの場合、ワーカー・ノード名はプライベート IP アドレスです。

    kubectl get nodes -o wide
    
  3. デバッグ・ポッド用の以下の YAML ファイルを作成し、enable-ssh.yaml として保存します。 <NODE_NAME> をワーカー・ノード名に置き換え、SSH_PUBLIC_KEY の例の value を公開 SSH 鍵に置き換えます。 ここでは、Docker alpine のイメージを例として使用しています。 ワーカーノードがパブリックなネットワークアクセスを持っていない場合、デバッグ用のイメージのコピーを自分の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. クラスター内にポッドを作成します。 このポッドの作成時、公開鍵がワーカー・ノードに追加され、root SSH ログインを許可するように SSH が構成されます。

    kubectl 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. 手順 2 で確認したワーカー・ノードに、秘密鍵を使用して SSH で接続します。

    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 アドレスを取得します。

    kubectl get nodes -o wide
    
  4. パブリック IP アドレスを介してワーカー・ノードに SSH で接続します。

    ssh -i <SSH_private_key_location> root@<WORKER_PUBLIC_IP>
    
  5. ipifconfigpingpscurl のような、情報収集や問題のトラブルシューティングに役立つデバッグコマンドを実行します。 apt install <tool> を実行して、デフォルトでインストールされていない可能性がある他のツール ( tcpdumpnc など) をインストールすることもできます。

デバッグ後のクリーンアップ

デバッグが終了したら、リソースをクリーンアップして SSH アクセスを無効にします。

  1. SSH 有効化ポッドを削除します。

    kubectl delete pod enable-ssh-<NODE_NAME>
    
  2. パブリック・ネットワークを介してワーカー・ノードにアクセスした場合は、ポート 22 が再度ブロックされるように、Calico ポリシーを削除します。

    calicoctl delete gnp ssh-open [-c <path_to_calicoctl_cfg>/calicoctl.cfg]
    
  3. 元の SSH 構成が使用され、追加された SSH 鍵が削除されるように、クラシック・ワーカー・ノードを再ロードするか、VPC ワーカー・ノードを置き換えます。