Rindrics Mumbles

kubeadm join したときに "net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" が原因で "couldn't validate the identity of the API Server" だったときの対応

公式のガイドではさらっと説明されている kubeadm join でつまづいたが、ネットワークの設定を見直すことで解決できた。

コンテキスト

  • Oracle Cloud Infrastructure(OCI)上に 3 ノード(1 master、2 workers)構成のオンプレ Kubernetes クラスタを立てようとしていた
  • master ノードと 2 基の worker ノードは同一のサブネット上に存在
  • master ノードはセットアップ済み
  • クラスタに worker ノードを追加するため、worker ノード用インスタンスから kubeadm join を試みている

状況

kubeadm join に対して以下のエラーが出ていた:

[preflight] Running pre-flight checks
error execution phase preflight: couldn't validate the identity of the API Server: Get "https://10.0.0.94:6443/api/v1/namespaces/kube-public/configmaps/cluster-info?timeout=10s": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
To see the stack trace of this error execute with --v=5 or higher

対応

L3 疎通を確認

そもそも疎通しているのかを確認する必要があると判断:

ping 10.0.0.94

ping に対して master ノードからの応答はなかった。

続いて、L3 レベルでの疎通を確認するために ARP テーブルを確認した:

arp
ubuntu@worker-node1:~$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
10.244.0.0               ether   MAC-ADDRESS        CM                    flannel.1
10.244.2.0               ether   MAC-ADDRESS        CM                    flannel.1
_gateway                 ether   MAC-ADDRESS        C                     enp0s3
master-node              ether   MAC-ADDRESS        C                     enp0s3
169.254.169.254          ether   MAC-ADDRESS        C                     enp0s3
worker-node              ether   MAC-ADDRESS        C                     enp0s3

ARP テーブルには master ノードが登録されていることから、L3 レベルでは疎通していることが確認できた。

そこで、L4 レベルでの断を疑い、ノードが接続されているサブネットのセキュリティ設定を確認することにした。

Virtual Cloud Network のセキュリティ設定を見直し

  • OCI の Virtual Cloud Network(VCN)にアクセス
  • 左カラムの “Security Lists” にアクセス
  • 対象 VCN インスタンス(サブネット)にアクセス
  • サブネット内からのアクセスを全プロトコルについて許可
Security Lists 選択画面

Security Lists 選択画面

“Security Lists” から目的のサブネットの Ingress 設定を確認すると、全サブネットおよび同一サブネット内からの ICMP プロトコル( ping が利用)が “Destination unreachable” となるような設定があった。

ping が通らなかったこと自体はこれらが原因

ping が通らなかったこと自体はこれらが原因

これらを削除すると、実際に ping が通った。 問題が L4 レベルでの疎通にありそうなことが確認できたので、削除した設定を元に戻しておいた。

同一サブネット内からの通信を許可

続いて、本来やりたかった kubeadm join を成功させるため、ここに同一サブネット内からの TCP 通信を許可する設定を加えたい。 …といいつつも、なんだかんだ UDP は使われそうだし、ICMP も使いそう。 この画面からは、許可するプロトコルの複数選択はできなかったので、”All protocols” を許可することにした(同一サブネット内ならまぁ問題ないでしょう)。

サブネット内からの通信について全てのプロトコルを許可

サブネット内からの通信について全てのプロトコルを許可

これで ping も通るようになったし、無事 kubeadm join も成功した。