K8S マスターノードの IP アドレスを変更するにはどうすればよいですか?それはあなたが思っているほど単純ではありません。

K8S マスターノードの IP アドレスを変更するにはどうすればよいですか?それはあなたが思っているほど単純ではありません。

昨日、ネットワーク環境に問題が発生しました。ローカル仮想マシンで構築されたKubernetes環境には固定IPがありませんでした。その結果、ノード IP が変更されました。もちろん、最も簡単な方法はノードを以前の IP アドレスに再固定することですが、私は頑固だったので、クラスターの IP アドレスを変更したいと考えました。その結果、途中でたくさんの落とし穴に陥ってしまいました。全然そんな簡単なことじゃないよ〜

環境

まず、以前の環境を見てみましょう。

~ cat / etc /ホスト
192.168.0.111マスター1
192.168.0.109ノード1
192.168.0.110 ノード2

新しい IP アドレス:

~ cat / etc /ホスト
192.168.0.106マスター1
192.168.0.101ノード1
192.168.0.105 ノード2

したがって、すべてのノードの IP アドレスを変更する必要があります。

操作する

まず、すべてのノードの /etc/hosts を新しいアドレスに変更します。

ヒント: ファイルを操作する前に、必ずバックアップすることを強くお勧めします。

マスターノードの /etc/kubernetes ディレクトリをバックアップします。

 ➜ cp - Rf / etc / kubernetes / / etc / kubernetes - bak

/etc/kubernetes 内のすべての構成ファイルの APIServer アドレスを置き換えます。

  古いIP = 192.168.0.111
新しいIP = 192.168.0.106
# 前を表示 ➜ 検索 . -タイプf | xargs grep $oldip
# IP アドレスを置き換えます ➜ find 。 -タイプf | xargs sed - i "s/$oldip/$newip/"
# 更新を確認する ➜ find 。 -タイプf | xargs grep $newip

古い IP アドレスを代替名として持つ /etc/kubernetes/pki 内の証明書を特定します。

 ➜ cd / etc / kubernetes / pki
➜ for f in $ ( find - name "*.crt" ) ;する
openssl x509 - in $f - text - noout > $f .txt ;
終わり
➜ grep - Rl $oldip 。
➜ for f in $ ( find - name "*.crt" ) ; rm $f .txtを実行します終わり

古い IP を参照する kube-system 名前空間で ConfigMap を見つけます。

 # kube - system 名前空間の下にあるすべての ConfigMap を取得します
➜ configmaps = $ ( kubectl -n kube -system get cm -o name | \
awk '{print $1}' | \
カット- d '/' - f 2 )

# すべてのConfigMapリソースリストを取得します ➜ dir = $ ( mktemp - d )
➜ $configmaps 内のcf の場合;する
kubectl - n kube - system は cm $cf - o yaml > $dir / $cf .yamlを取得します
終わり

# 古いIPを含むすべてのConfigMapを検索
➜ grep - Hn $dir /* -e $oldip

# 次に、これらのConfigMapを編集し、古いIPを新しいIPに置き換えます
➜ kubectl -n kube-system を編集 cm kubeadm-config
➜ kubectl -n kube-system edit cm kube-proxy

このステップは非常に重要です。操作中にこの手順を無視したため、Flannel CNI が起動に失敗し、次のログ情報のようなエラーが報告され続けました。

 ➜ kubectl ログ- f kube - flannel - ds - pspzf - n kube -システム
I0512 14 : 46 : 26.044229 1 main.go : 205 ] CLIフラグconfig : { etcdEndpoints : http : //127.0.0.1 : 4001 http : //127.0.0.1 : 2379etcdPrefix : /coreos.com/networketcdKeyfile : etcdCertfile : etcdCAFile : etcdUsername : etcdPassword : version : falsekubeSubnetMgr : truekubeApiUrl : kubeAnnotationPrefix : flannel.alpha.coreos.comkubeConfigFile : iface: [ ens33 ] ifaceRegex :[] ipMasq : truesubnetFile : / run / flannel / subnet .env publicIP : publicIPv6 : subnetLeaseRenewMargin : 60 healthzIP : 0.0 .0 .0 healthzPort : 0 iptablesResyncSeconds : 5 iptablesForwardRules : true netConfPath : / etc / kube - flannel / net - conf .json setNodeNetworkUnavailable : true }
W0512 14 : 46 : 26.044617 1 client_config .go : 614 ] --kubeconfig も --master も指定されていません。 inClusterConfig を使用します。これは機能しない可能性があります。
E0512 14 : 46 : 56.142921 1 main .go : 222 ] SubnetManager の作成に失敗しました: 'kube-system/kube-flannel-ds-pspzf'のポッド仕様の取得中にエラーが発生しました: "https://10.96.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-pspzf"を取得しました: tcp 10.96 .0 .1にダイヤルしました: 443 : i / o タイムアウト

実際のところ、API サーバーに接続できませんでした。長時間のトラブルシューティングの後、kube-proxy ログを確認することを思い出しました。そこには次のエラー メッセージが表示されていました。


E0512 14 : 53 : 03.260817 1 reflector .go : 138 ] k8s .io / client - go / informers / factory .go : 134 : * v1 .EndpointSliceの監視に失敗しました: * v1 .EndpointSliceの一覧表示に失敗しました: "https://192.168.0.111:6443/apis/discovery.k8s.io/v1/endpointslices?labelSelector=%21service.kubernetes.io%2Fheadless%2C%21service.kubernetes.io%2Fservice-proxy-name&limit=500&resourceVersion=0"を取得しました: tcp 192.168 .0 .111にダイヤルしました: 6443 :接続しました:ホストへのルートがありません

これは、kube-proxy ConfigMap で設定されている apiserver アドレスが古い IP アドレスであるため、新しい IP アドレスに置き換える必要があるためです。

手順 3 で抽出した証明書と秘密キーを削除し、これらの証明書を再生成します。

 ➜ cd / etc / kubernetes / pki
➜ rm apiserver .crt apiserver .key
➜ kubeadm init フェーズ certs apiserver
➜ rm etcd /ピア.crt etcd /ピア.key
➜ kubeadm init フェーズ certs etcd -ピア

もちろん、すべてを再生成することもできます。

 ➜ kubeadm init フェーズですべての証明書を取得

新しい kubeconfig ファイルを生成します。

 ➜ cd / etc / kubernetes
➜ rm -f admin .conf kubelet .confコントローラー-マネージャー.confスケジューラー.conf
➜ kubeadm initフェーズ kubeconfig all
I0513 15 : 33 : 34.404780 52280バージョン.go : 255 ]リモート バージョンの方がずっと新しいです: v1 .24 .0 ;フォールバック:安定版- 1.22
[ kubeconfig ] kubeconfig フォルダ"/etc/kubernetes"を使用する
[ kubeconfig ] 「admin.conf」 kubeconfig ファイルの書き込み
[ kubeconfig ] 「kubelet.conf」 kubeconfigファイルの書き込み
[ kubeconfig ] 「controller-manager.conf」 kubeconfigファイルの書き込み
[ kubeconfig ] 「scheduler.conf」 kubeconfig ファイルの書き込み
# デフォルトのkubeconfigファイルを上書きします ➜ cp /etc/kubernetes/admin.conf $ HOME / .kube / config

kubelet を再起動します。

 ➜ systemctl コンテナを再起動します
➜ systemctl kubeletを再起動します

Kubernetes クラスターにアクセスできるようになりました。

 ➜ kubectl ノードを取得する
名前 ステータス 役割 年齢 バージョン
master1 準備完了コントロールプレーン マスター48d v1.22.8
ノード1 NotReady <なし> 48 d v1 .22 .8
ノード2 NotReady <なし> 48 d v1 .22 .8

ノード

クラスターには現在アクセスできますが、Node ノードが NotReady 状態になっていることがわかります。 node2 の kubelet ログを確認できます。

 ➜journalctl -u kubelet -f
......
5 13日15:47:55 node2 kubelet [ 1194 ] : E0513 15 : 47 : 55.470896 1194 kubelet.go : 2412 ] 「ノードの取得エラー」 err = 「ノード\ " node2\" 見つかりません」
5 13日15:47:55 node2 kubelet [ 1194 ] : E0513 15 : 47 : 55.531695 1194 reflector.go : 138 ] k8s.io/client-go/informers/factory.go:134 :監視に失敗まし* v1.Service : 一覧表示失敗しました* v1.Service : 「https://192.168.0.111:6443/api/v1/services?limit=500&resourceVersion=0」 取得: tcp 192.168.0.111 ダイヤル: 6443 : 接続: ホストへのルートありませ
5 13日15:47:55 node2 kubelet [ 1194 ] : E0513 15 : 47 : 55.571958 1194 kubelet.go : 2412 ] 「ノードの取得エラー」 err = 「ノード\ " node2\" 見つかりません」
5 13日15:47:55 node2 kubelet [ 1194 ] : E0513 15 : 47 : 55.673379 1194 kubelet.go : 2412 ] 「ノードの取得エラー」 err = 「ノード\ " node2\" 見つかりません」

以前の APIServer アドレスが引き続きアクセスされていることがわかります。では、APIServer アドレスはどこで明示的に使用されるのでしょうか?次のコマンドで kubelet の起動パラメータを表示できます。

 ➜ systemctl ステータス kubelet
● kubelet .service - kubelet : Kubernetes ノード エージェント
ロード済み: ロード済み( /usr/lib/systemd/system/kubelet.service ; 有効; ベンダープリセット: 無効)
ドロップイン: /usr/lib/systemd/system/kubelet.service.d
└─10 - kubeadm.conf
アクティブ: 2022-05-13 金曜日14:37:31 CST からアクティブ( 実行) 1時間13分前
ドキュメント: https://kubernetes.io/docs/
メイン PID : 1194 ( kubelet )
タスク: 15
メモリ: 126.9M
Cグループ: /system.slice/kubelet.service
└─1194 / usr / bin / kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kub...

5 月13 日15 : 51 : 08 node2 kubelet [ 1194 ] : E0513 15 : 51 : 08.787677 1194 kubelet .go : 2412 ] "ノード取得エラー" err = "ノード \"node2... が見つかりました"
5 月13 日15 : 51 : 08 node2 kubelet [ 1194 ] : E0513 15 : 51 : 08.888194 1194 kubelet .go : 2412 ] "ノード取得エラー" err = "ノード \"node2... が見つかりました"
......

コア設定ファイルは /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf で、その内容は次のとおりです。

  cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
# 注意:このドロップインはkubeadm kubelet v1.11 以降でのみ動作します
[サービス]
環境= "KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
環境= "KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# これは、「kubeadm init」 「kubeadm join」が実行時に生成し KUBELET_KUBEADM_ARGS変数を動的に設定するファイルです
環境ファイル=-/ var / lib / kubelet / kubeadm - flags.env
# これは、ユーザーが最後の手段としてkubelet 引数をオーバーライドするために使用できるファイルです。できればユーザーは
# 代わりに、構成ファイル内の.NodeRegistration .KubeleExtraArgsオブジェクトを使用します。 KUBELET_EXTRA_ARGS はこのファイルから取得する必要があります。
環境ファイル=-/ etc / sysconfig / kubelet
実行開始=
ExecStart =/ usr / bin / kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf という構成があり、2 つの構成ファイル bootstrap-kubelet.conf と kubelet.conf が指定されています。最初のファイルが存在しません:

  cat /etc/kubernetes/bootstrap-kubelet.conf
cat : / etc / kubernetes / bootstrap - kubelet .conf :そのようなファイルまたはディレクトリはありません

2 番目の構成ファイルは、kubeconfig ファイルの形式です。このファイルは APIServer のアドレスを指定します。以前の IP アドレスのままであることがわかります。

  /etc/kubernetes/kubelet.conf を編集します
APIバージョン: v1
クラスター:
-クラスター:
証明書-機関-データ: < ...... >
サーバー: https://192.168.0.111:6443
名前:デフォルト-クラスター
コンテキスト:
-コンテクスト
クラスター:デフォルト-クラスター
名前空間:デフォルト
ユーザー:デフォルト-認証
名前:デフォルト-コンテキスト
現在のコンテキスト:デフォルトのコンテキスト
種類:設定
設定: { }
ユーザー:
-名前:デフォルト-認証
ユーザー:
クライアント- 証明書: /var/lib/kubelet/pki/kubelet-client-current.pem
クライアント- キー: /var/lib/kubelet/pki/kubelet-client-current.pem

したがって、最初に考えることは、ここで APIServer アドレスを新しい IP アドレスに変更することですが、関連する証明書が以前のままであり、再生成する必要があるため、明らかに問題が発生します。では、ファイルを再生成するにはどうすればよいでしょうか?

まず、kubelet 作業ディレクトリをバックアップします。

  cp /etc/kubernetes/kubelet.conf /etc/kubernetes/kubelet.conf .bak
➜ cp - rf / var / lib / kubelet / / var / lib / kubelet - bak

kubelet クライアント証明書を削除します。

 ➜ rm / var / lib / kubelet / pki / kubelet -クライアント*

次に、master1 ノード (/etc/kubernetes/pki/ca.key ファイルがあるノード) に kubelet.conf ファイルを生成します。

 # マスター1ノードで ➜ kubeadm kubeconfig user --org system:nodes --client-name system:node:node2 --config kubeadm.yaml > kubelet.conf

次に、kubelet.conf ファイルを node2/etc/kubernetes/kubelet.conf にコピーし、node2 で kubelet を再起動して、/var/lib/kubelet/pki/kubelet-client-current.pem が再作成されるのを待ちます。

 ➜ systemctl kubeletを再起動します
# 再起動後にkubeletクライアント証明書が再生成されるのを待ちます ➜ ll / var / lib / kubelet / pki /
合計12
- rw ------- 1 ルート ルート 1106 5月13日 16:32 kubelet-client-2022-05-13-16-32-35.pem
lrwxrwxrwx 1 ルートroot 59 5 月13 日16:32 kubelet - クライアント- 現在の.pem - > / var / lib / kubelet / pki / kubelet - client - 2022-05-13-16-32-35.pem
- rw - r --r-- 1 ルート ルート 2229 3 月 26 日 14:39 kubelet.crt
- rw ------- 1 ルート root 1675 3 月 26 日 14:39 kubelet.key

kubelet.conf を手動で編集して、ローテーションする kubelet クライアント証明書を指すようにし、ファイル内の client-certificate-data と client-key-data を /var/lib/kubelet/pki/kubelet-client-current.pem に置き換えるのが最適です。

 クライアント- 証明書: /var/lib/kubelet/pki/kubelet-client-current.pem
クライアント- キー: /var/lib/kubelet/pki/kubelet-client-current.pem

kubelet をもう一度再起動します。これでノード2は準備完了状態になります。同じ方法を使用して、node1 を再度構成します。

 ➜ kubectl ノードを取得する
名前 ステータス 役割 年齢 バージョン
master1 準備完了コントロールプレーン マスター48d v1.22.8
ノード1 準備完了<なし> 48 d v1 .22 .8
ノード2 準備完了<なし> 48 d v1 .22 .8

推奨方法

上記の操作方法は通常はニーズを満たすことができますが、関連する証明書についてある程度理解している必要があります。この方法に加えて、さらに簡単な操作があります。

まず、kubelet を停止し、作業するディレクトリをバックアップします。

 ➜ systemctl を停止します
➜ mv / etc / kubernetes / etc / kubernetes -バックアップ
➜ mv / var / lib / kubelet / / var / lib / kubelet - bak

pki 証明書ディレクトリを保存します:

 ➜ mkdir -p / etc / kubernetes
➜ cp - r / etc / kubernetes - bak / pki / etc / kubernetes
➜ rm / etc / kubernetes / pki / { apiserver. * etcd /ピア。 * }
rm :通常のファイル' /etc/kubernetes/pki/apiserver.crt ' を削除しますか?ええ
rm :通常のファイル' /etc/kubernetes/pki/apiserver.key 'を削除しますか? ええ
rm :通常のファイル' /etc/kubernetes/pki/etcd/peer.crt ' 削除します?ええ
rm :通常のファイル' /etc/kubernetes/pki/etcd/peer.key ' 削除します?ええ

ここで、次のコマンドを使用してコントロール プレーン ノードを再初期化しますが、最も重要なことは etcd データ ディレクトリを使用することです。--ignore-preflight-errors=DirAvailable --var-lib-etcd フラグを使用して、既存の etcd データを使用するように kubeadm に指示できます。

 ➜ kubeadm init --config kubeadm.yaml --ignore-preflight-errors=DirAvailable--var-lib-etcd
[ init ] Kubernetes バージョン使用: v1.22.8
[プリフライト] プリフライトチェックの実行
[警告 DirAvailable --var-lib-etcd]: /var/lib/etcd が空ではありません
[事前準備] Kubernetes クラスターの設定に必要なイメージを取得する
......
Kubernetes コントロールプレーンが正常に初期化されました
クラスターの使用を開始するには通常のユーザーとして以下を実行する必要があります
mkdir -p $HOME / .kube
sudo cp -i /etc/kubernetes/admin.conf $ HOME / .kube / config
sudo chown $ ( id - u ) : $ ( id - g ) $HOME / .kube / config
あるいは root ユーザーの場合は以下を実行できます
KUBECONFIG =/ etc / kubernetes / admin.confをエクスポートします。
ここで、クラスターにポッド ネットワークをデプロイする必要があります。
以下にリストされているオプションのいずれかを使用して、 「kubectl apply -f [podnetwork].yaml」を実行します
https://kubernetes.io/docs/concepts/cluster-administration/addons/
次に、各ワーカーノードroot として以下を実行することで、任意の数のワーカーノードに参加できます
kubeadm join 192.168 .0 .106 : 6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:27993cae9c76d18a1b82b800182c4c7ebc7a704ba1093400ed886f65e709ec04

上記の操作は、クラスターを通常どおり初期化する場合とほぼ同じです。唯一の違いは、--ignore-preflight-errors=DirAvailable--var-lib-etcd パラメータが追加されていることです。これは、以前の etcd データを使用することを意味します。次に、APIServer の IP アドレスが新しいアドレスになったかどうかを確認します。

cp -i /etc/kubernetes/admin.conf $ HOME / .kube / config
cp : ' /root/.kube/config ' を上書きしますか?ええ
➜ kubectl クラスター-情報
Kubernetes コントロールプレーンはhttps://192.168.0.106:6443 ​ で実行されています
CoreDNS https://192.168.0.106:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy ​​​​​​​​​​​​​ で実行されています

クラスターの問題をさらにデバッグし診断するには 「kubectl cluster-info dump」を使用します。

ノードについては、リセットしてクラスターに再参加させることができます。

 # ノード上の操作 ➜ kubeadm reset

リセット後、クラスターに再度参加します。

 # ノードの操作 ➜ kubeadm join 192.168.0.106:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:27993cae9c76d18a1b82b800182c4c7ebc7a704ba1093400ed886f65e709ec04

この方法は上記の方法よりもはるかに簡単です。正常に動作した後は、クラスターも正常です。

 ➜ kubectl ノードを取得する
名前 ステータス 役割 年齢 バージョン
master1 準備完了コントロールプレーン マスター48d v1.22.8
ノード1 準備完了<なし> 48 d v1 .22 .8
node2 準備完了<なし> 4 m50s v1 .22 .8

要約する

IP 変更によるビジネスへの影響を回避するには、Kubernetes クラスター ノードの IP アドレスに静的 IP アドレスを使用するのが最適です。静的 IP でない場合は、IP が変更されたときにドメイン名を直接再マップできるように、署名用のカスタム ドメイン名を追加することを強くお勧めします。以下に示すように、kubeadm 構成ファイルの ClusterConfiguration を通じて apiServer.certSANs を構成するだけで済みます。

 apiバージョン: kubeadm .k8s .io / v1beta3
apiサーバー:
タイムアウトForControlPlane : 4分0秒
certSANs :
-api.k8s.local
-マスター1
- 192.168 .0 .106
種類: ClusterConfiguration
......

certSAN に追加する必要があるアドレスを追加します。たとえば、ここでは api.k8s.local という追加アドレスを追加します。これにより、将来 IP が変更された場合でも、このドメイン名を新しい IP アドレスに直接マッピングできます。同様に、外部ネットワーク アクセス IP を介してクラスターにアクセスする場合は、署名認証用に外部ネットワーク IP アドレスも追加する必要があります。


<<:  コンテナクラウドプラットフォームの運用・保守の考え方や手法を学ぶ

>>:  ビジュアルクラウドアーキテクチャの5つの柱

推薦する

ウェブマスターがウェブサイトのトラフィック増加を効果的に維持する方法について簡単に説明します。

ウェブサイトにトラフィックがあるからといって、それが成功を意味するわけではなく、それは成功の始まりに...

友情リンクの効果を最大化する

ウェブサイトを構築したら、宣伝を始めるべきでしょうか? ユーザーにインターネット上であなたのサイトを...

スムーズな運転、華雲データと盛世大連が提携し自動車サービス向けインテリジェントソリューションを模索

5G、ビッグデータ、IoTなどの最先端技術の発展により、新しいテクノロジーがもたらす可能性は、旅行や...

投稿した外部リンクはすべて効果的ですか?

外部リンクを作成する場合、作成した外部リンクが有効かどうか、また、含まれているかどうかを確認する必要...

cloudsilk: トリプルネットワークの米国聯通 AS4837 回線 VPS、2.5Gbps 帯域幅、年間 160 元から

Cloudsilkは長年にわたり米国サンノゼデータセンターでVPSを提供しており、その中でもChin...

バーチャルオペレーター:現状、問題点、解決策

概要: ライセンスが発行されてから半年以上が経ち、仮想オペレーターのモバイル再販ビジネスは、萌芽から...

SAP: パートナーと協力して顧客の変革を推進

[51CTO.comより引用] 現在、疫病、環境、政治情勢などによってもたらされるさまざまな不確実性...

ウェブサイトの顧客コンバージョン率を向上させる方法に関する簡単な分析

ウェブサイトを構築する目的は、ウェブサイトを通じて、特定の顧客からの相談、顧客の協力、顧客の購入をも...

hiformance-5 USD/KVM/3 GB RAM/30 GB HDD/3 TB Flow/ユタ

新規加盟店の Hiformance は、ユタ州のデータセンターで KVM 仮想 VPS を暫定的に運...

WeChatは「四方八方から待ち伏せ」されており、ソーシャルトラックは簡単には諦めないだろう!

2016年初頭、28歳の張連安さんはWeChatのエンジニアの仕事を辞め、すぐに新しいソーシャルプロ...

Vipshop は損益分岐点に近づいています。垂直型 B2C は収益性の高い時代を先導するでしょうか?

2011年第1四半期以降のVipshopの収益2011年第1四半期以降のVipshopの純利益推移チ...

2018年中国オンライン旅行市場の洞察

流行の影響により、中国のオンライン観光市場の規模はほぼ半減し、2019年と比較して前年比で約50%減...

locvps: 22 元/月、US CN2 VPS、1G メモリ/1 コア/30g SSD/400g トラフィック/150M 帯域幅

locvpsは現在、米国ロサンゼルスデータセンターの「ロサンゼルス#2(BGP+CN2)」シリーズV...

SEOとPPCの相互補完について

近年、検索エンジン マーケティングに取り組む企業がますます増えています。SEO を選択する企業もあれ...