複数NICを持つノードで、特定NICを使ってk8sクラスタを構成する
この記事は何?
下図のように、各マシンで2つのNIC(eth0とeth1)が使用されているケースを考えます。
(node0の3つめのNICeth2には実験用機器がありますが、この記事には関係ない…はずでした)
普段インターネットへの接続等に使用しているのはeth0の先の赤色のネットワーク。でもkubernetesのノード間通信には、eth1の先の紫色のネットワークを使ってほしく、各ノードのIPもeth1のものであってほしいとします。
(状況としては、紫のネットワークが赤より高速な場合など)
この要件を満たしたkubernetesクラスタを構築しようとしたものの、意外とハマったので備忘録を残します。
前提条件
- 各ノード、各NICのIPは固定済、
10.0.0.0/24のIPレンジで紫色のネットワークに到達するよう、ルーティングも行っていること。 - 全てのノードでkubeadmのインストールに従い
-
kubeadm、kubelet、kubectlがインストールされていること (バージョンは1.16.15-00を使用) - ファイアウォール(
UFW)が適切に設定済みであること
-
- (決め事)
node0をマスターノード、node1をワーカーノードとする、シングルコントロールプレーンクラスタを構築する - (決め事) CNIプラグインには
calicoを使用する
普通にクラスタ構築し、問題発生するまで
公式ドキュメントを参考に、クラスタ構築を進めます。
# 初期化
# (心の声) --apiserver-advertise-addressをnode0のeth1のIPにしたから、あとはいい感じに紫色ネットワーク使ってくれるよね
# kubectl join用の認証情報はメモっておく
sudo kubeadm init --control-plane-endpoint=10.0.0.100:6443 \
--apiserver-advertise-address=10.0.0.100 \
--pod-network-cidr=10.1.0.0/16
# kubectl で操作できるように
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# calico インストール
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
# masterノードでもpodを動かせるように
kubectl taint nodes --all node-role.kubernetes.io/master-
# node1をクラスタに追加
# **node1で下記を実行**
node1> sudo kubeadm join 10.0.0.100:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
これでクラスタ構築はおしまい。kubectl init時に--apiserver-advertise-addressをnode0のeth1のIPにしたから、あとはいい感じに紫色ネットワーク使ってくれるよね、と思っていました。
あとはkubernetes-dashboard入れて、他にもアプリケーションデプロイ…と色々設定進めていたところ、問題に気づきました
問題の発覚
kubernetes-dashboardアクセス時にネットワークエラー発生(失念しましたが、503 Bad Gatewayだったかな...?)。
更に調査をすすめると、ノード間の通信が成立していなさそうな雰囲気。
もしやと思って、ノードIPを下記で取得
# -o wide オプションを付けないと、ノードIPは表示されない
> kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP (略)
node0 Ready master 12m v1.16.15 172.16.0.4 (略)
node1 Ready <none> 5m v1.16.15 192.168.1.21 (略)
INTERNAL-IPが想定と違う。
node0は、全然関係ないはずの実験用機器向けのIPを、node1は赤色ネットワークのIPを使っていた。
対処
色々試したところ、下記2つの施策により、
- ノード(の
INTERNAL-IP)をeth1のアドレスにする -
eth1の紫色ネットワークでpod間通信を行う
を実現出来ました
1.ノードINTERNAL-IPの変更
こちらの記事を参考に、kubecel起動時の引数を変更してINTERNAL-IPを変更(明示的に指定)します
# kubeletのservice設定ファイルを編集
sudo vim /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
設定ファイル内のEnvironment変数(の中のKUBELET_CONFIG_ARGS)を下記のように変更します
# 変更前
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# 変更後
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --node-ip=10.0.0.100"
## node1の場合、10.0.0.101
変更後は下記でサービスを再起動します
sudo systemctl daemon-reload
sudo systemctl restart kubelet
INTERNAL-IPが適切に変更されていることを確認します
> kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP (略)
node0 Ready master 17m v1.16.15 10.0.0.100 (略)
node1 Ready <none> 12m v1.16.15 10.0.0.101 (略)
2.calicoのBGP Networking設定変更
こちらのドキュメントを参考に、calicoのルーティング設定を変更します。
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=eth1
これで、紫色ネットワークを使用してルーティングを行ってくれます。
所感
(自前でのクラスタ運用、やっぱ面倒…マネージド使いたい)
Discussion